使用任務並行庫時如何處理所有未處理的異常?
我在 .NET 4.0 中使用 TPL(任務並行庫)。我想通過使用
Thread.GetDomain().UnhandledException事件來集中所有未處理異常的處理邏輯。但是,在我的應用程序中,從不會為以 TPL 程式碼啟動的執行緒觸發該事件,例如Task.Factory.StartNew(...). 如果我使用類似new Thread(threadStart).Start().這篇 MSDN 文章建議在使用 TPL 時使用 Task.Wait() 來捕捉
AggregateException,但這不是我想要的,因為這種機制不夠“集中”。有沒有人遇到過同樣的問題,還是只有我一個人?你有什麼解決辦法嗎?
似乎沒有內置的方法來處理這個問題(幾乎 2 週後沒有回答這個問題)。我已經推出了一些自定義程式碼來解決這個問題。解決方案描述很長,所以我已經在我的部落格中發布了。有興趣可以參考這篇文章。
**2010 年 5 月 7 日更新:**我找到了一種更好的方法,即利用任務延續。我創建了一個
class ThreadFactory暴露 Error 事件的事件,該事件可由頂級處理程序訂閱,並提供方法來啟動附加正確延續的任務。程式碼張貼在這裡。
**2011 年 4 月 18 日更新:**根據 Nifle 的評論從部落格文章中發布程式碼。
internal class ThreadFactory { public delegate void TaskError(Task task, Exception error); public static readonly ThreadFactory Instance = new ThreadFactory(); private ThreadFactory() {} public event TaskError Error; public void InvokeError(Task task, Exception error) { TaskError handler = Error; if (handler != null) handler(task, error); } public void Start(Action action) { var task = new Task(action); Start(task); } public void Start(Action action, TaskCreationOptions options) { var task = new Task(action, options); Start(task); } private void Start(Task task) { task.ContinueWith(t => InvokeError(t, t.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously); task.Start(); } }
我認為TaskScheduler.UnobservedTaskException 事件是你想要的:
當故障任務的未觀察到的異常即將觸發異常升級策略時發生,預設情況下,該策略將終止程序。
因此,此事件類似於
DomainUnhandledException您在問題中提到的事件,但僅針對任務發生。順便說一句,未觀察到的異常政策(是的,這不是未觀察到的異常,MS 傢伙又發明了新詞……),從 .NET 4.0 更改為 .NET 4.5。在 .NET 4.0 中未觀察到的異常會導致程序終止,但在 .NET 4.5 中 - 不要。這都是因為我們將在 C# 5 和 VB 11 中擁有新的非同步內容。