[C#.NET][TPL] Task Receive Information for Exception
捕捉任務例外會需要用到以下:
- AggregateException 類別:用來捕捉平行運算函式庫的例外訊息
- InnerExceptions 屬性,取得例外集合
- InnerException 屬性,取得目前例外
通知任務步驟:
- 利用 Task.ContinueWith 方法,調用子任務。
- 使用 TaskContinuationOptions.OnlyOnFaulted 列舉,做為子任務啟用條件。
更多的內容請參考:
http://msdn.microsoft.com/zh-tw/library/dd537614.aspx
讓我們來看看實際的例子:
- 在 mainTask 主要任務裡模擬一個例外。
- 主任務若是發生例外,方能啟動子任務,傳入 TaskContinuationOptions.OnlyOnFaulted 參數 。
- 子任務等待主任務完成,然後捕捉例外。
private SynchronizationContext m_SynchronizationContext; public Form1() { InitializeComponent(); m_SynchronizationContext = SynchronizationContext.Current; }
private void DoWork12() { var mainTask = new Task(() => { int counter = 0; while (true) { counter++; if (counter == 5) { throw new Exception("模擬例外"); } //update UI m_SynchronizationContext.Post(_ => { this.label1.Text = counter.ToString(); }, null); SpinWait.SpinUntil(() => false, 100); } }); mainTask.Start(); mainTask.ContinueWith(task => { StringBuilder sb = new StringBuilder(); try { task.Wait(); } catch (AggregateException ex) { foreach (var innerException in ex.InnerExceptions) { sb.AppendLine(innerException.ToString()); } } finally { var status = string.Format("任務完成,完成狀態為:\rIsCanceled={0}\rIsCompleted={1}\rIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted); sb.AppendLine(status.ToString()); MessageBox.Show(sb.ToString()); } }, TaskContinuationOptions.OnlyOnFaulted); }
當調用DoWork12方法後,結果如下:
也可以用 Task.IsFaulted 判斷是否有例外,然後再獲取 Task.Exception.InnerExceptions 唯讀集合內的例外訊息。
private void DoWork13() { var mainTask = new Task(() => { int counter = 0; while (true) { counter++; if (counter == 5) { throw new Exception("模擬例外"); } //update UI m_SynchronizationContext.Post(_ => { this.label1.Text = counter.ToString(); }, null); SpinWait.SpinUntil(() => false, 100); } }); mainTask.Start(); mainTask.ContinueWith(task => { StringBuilder sb = new StringBuilder(); if (task.IsFaulted) { foreach (var innerException in task.Exception.InnerExceptions) { sb.AppendLine(innerException.ToString()); } } var finish = string.Format("任務完成,完成狀態為:\rIsCanceled={0}\rIsCompleted={1}\rIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted); sb.AppendLine(finish); MessageBox.Show(sb.ToString()); }, TaskContinuationOptions.OnlyOnFaulted); }
當調用DoWork13方法後,結果如下:
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET