簡體   English   中英

如何使用ContinueWith正確管理任務中的異常

[英]How to manage properly an exception in a Task with ContinueWith

在閱讀有關任務和exepcion管理的信息后,我使用此代碼來管理任務中拋出的異常:

Task<Object> myTask = Task.Factory.StartNew<Object>(doTask, CancellationToken.None,   TaskCreationOptions.None, TaskScheduler.Default);
myTask .ContinueWith(task => afterTask(task), TaskScheduler.FromCurrentSynchronizationContext());

doTask和AfterTask在哪里:

private <Object> doTask() {
    throw new Exception("BOOM");
}

private afterTask(Task<Object> aTask) {

        if (aTask.IsFaulted)
        {
            MessageBox.Show(aTask.Exception.InnerException.Message);
        }
        else //whatever
}

拋出Exception Boom時,Visual Studio會顯示一條警告,通知未捕獲異常但如果我繼續執行異常則在afterTask函數中處理。

這段代碼是正確的還是我錯過了解任務的一些基本行為? 有什么辦法可以避免調試器發出沒有捕獲到execption的警告? 有點煩人......

提前致謝

試試這個:

 task.ContinueWith(
            t =>
            t.Exception.Handle(ex =>
                                   {
                                       logger.Error(ex.Message, ex);
                                       return false;
                                   })

            , TaskContinuationOptions.OnlyOnFaulted
            );

通過使用TaskContinuationOptions.OnlyOnFaulted ,只有在原始任務拋出異常時才運行ContinueWith塊。

另外,您可以選擇是否從傳遞給Handle的lambda返回true或false,指示是否已處理異常。 就我而言,我不想阻止異常傳播。 您可能希望將其更改為在您的情況下返回true

        try
        {
            var t1 = Task.Delay(1000);

            var t2 = t1.ContinueWith(t =>
            {
                Console.WriteLine("task 2");
                throw new Exception("task 2 error");
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

            var t3 = t2.ContinueWith(_ =>
            {
                Console.WriteLine("task 3");
                return Task.Delay(1000);
            }, TaskContinuationOptions.OnlyOnRanToCompletion).Unwrap();

            // The key is to await for ALL tasks rather than just
            // the first or last task.
            await Task.WhenAll(t1, t2, t3);
        }
        catch (AggregateException aex)
        {
            aex.Flatten().Handle(ex =>
                {
                    // handle your exceptions here
                    Console.WriteLine(ex.Message);
                    return true;
                });
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM