Dot-Net

使用任務並行庫時如何處理所有未處理的異常?

  • April 25, 2010

我在 .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 中擁有新的非同步內容。

引用自:https://stackoverflow.com/questions/2707295