這意味着什麼以及如何解決它?通過等待任務或訪問其異常屬性未觀察到任務的異常。因此,未被發現的例外是
我正在使用TPL任務。
整個誤差
任務的異常(或多個)未觀察到無論是等待在Task或訪問其Exception屬性。結果,未被觀察到的異常被終結器線程重新拋出。
在System.Threading.Tasks.TaskExceptionHolder.Finalize()
的mscorlib
這意味着什麼以及如何解決它?通過等待任務或訪問其異常屬性未觀察到任務的異常。因此,未被發現的例外是
我正在使用TPL任務。
整個誤差
任務的異常(或多個)未觀察到無論是等待在Task或訪問其Exception屬性。結果,未被觀察到的異常被終結器線程重新拋出。
在System.Threading.Tasks.TaskExceptionHolder.Finalize()
的mscorlib
如果您創建一個任務,你永遠不要叫task.Wait()
或嘗試檢索Task<T>
的結果,當垃圾收集器收集任務時,它將在最終確定期間拆除您的應用程序。有關詳細信息,請參閱MSDN的頁面Exception Handling in the TPL。
這裏最好的選擇是「處理」異常。這可以通過延續完成 - 您可以將延續附加到任務,並記錄/吞下/等發生的異常。這提供了一個乾淨的方式來登錄任務異常,並可以寫成一個簡單的擴展方法,即:
public static void LogExceptions(this Task task)
{
task.ContinueWith(t =>
{
var aggException = t.Exception.Flatten();
foreach(var exception in aggException.InnerExceptions)
LogException(exception);
},
TaskContinuationOptions.OnlyOnFaulted);
}
通過上述,您可以防止拆除的應用程序,並記錄它,通過任何任務:
Task.Factory.StartNew(() =>
{
// Do your work...
}).LogExceptions();
或者,您可以訂閱TaskScheduler.UnobservedTaskException和處理它。
當然;這意味着一個Task
被留在垃圾回收後被終結,但任務本身失敗。有兩種解決方法:
ContinueWith(...)
認購,並在參數檢查.IsFaulted
和.Exception
在Task
)TaskScheduler.UnobservedTaskException
事件,並將其標記觀察(調用e.SetObserved()
後記錄錯誤)+1 - 有一個補充 - 如果你的延續除了檢查'IsFaulted'外什麼都沒做,你可以使用'OnlyOnFaulted'延續選項並避免手動檢查... –
實際上這發生在我調用內部公共靜態函數的地方的tpl任務。使用try catch會解決這個問題?我真的需要創建另一個任務並等待它嗎?感謝 – MonsterMMORPG
+1,因爲需要調用'UnobservedTaskExceptionEventArgs'上的'SetObserved'。 –
試試這個:
public static void ThrowFirstExceptionIfHappens(this Task task)
{
task.ContinueWith(t =>
{
var aggException = t.Exception.Flatten();
foreach (var exception in aggException.InnerExceptions)
{
throw exception; // throw only first, search for solution
}
},
TaskContinuationOptions.OnlyOnFaulted); // not valid for multi task continuations
}
public static Task CreateHandledTask(Action action)
{
Task tsk = Task.Factory.StartNew(action);
tsk.ThrowFirstExceptionIfHappens();
return tsk;
}
_Its one _ ???你什麼意思?你能解釋一下你的答案對答案的貢獻嗎? –
你剛剛通過繼續創建了一個新任務,然後失敗並進入相同的狀態。 –
對於增加了娛樂功能,在一個名爲你選擇的四個字母的單詞的類中有一個靜態存根方法'Off',並將它用於你的全部延續。有助於打擊來自這個特殊例外的一些被壓抑的挫敗感。 – Aaronaught
實際上,這發生在我稱爲tpl任務內部的公共靜態函數的地方。使用try catch會解決這個問題?我真的需要創建另一個任務並等待它嗎? – MonsterMMORPG
@MonsterMMORPG:捕獲異常的函數(公共靜態)中的try catch會處理它。問題是一個例外是「冒泡」到任務本身,並且你從不等待任務完成。如果你這樣做,它會解決它。 –