[C#.NET][TPL] 任務例外通知

[C#.NET][TPL] Task Receive Information for Exception

捕捉任務例外會需要用到以下:

通知任務步驟:

 

更多的內容請參考:

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方法後,結果如下:

SNAGHTML393e4e51


也可以用 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方法後,結果如下:

SNAGHTML39536b78

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo