日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Async下处理多个异常

發布時間:2024/4/11 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Async下处理多个异常 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

???? Task Parallel Library (TPL) 中,當你使用async/await?語法關鍵字時,你可能遇到以下異常處理的情況: Catch 塊只會處理第一個異常而忽略其它的異常。來看下面代碼塊:

1: private static async void TestCatchExceptionWithTPL() 2: { 3: try 4: { 5: await Task.Factory.StartNew(() => 6: { 7: Task.Factory.StartNew(() => 8: { throw new NullReferenceException(); }, 9: TaskCreationOptions.AttachedToParent); 10: Task.Factory.StartNew(() => 11: { throw new ArgumentException(); }, 12: TaskCreationOptions.AttachedToParent); 13: }); 14: } 15: catch (AggregateException aex) 16: { 17: // this catch will never be target 18: } 19: catch (Exception ex) 20: { 21: Console.WriteLine("## {0} ##", ex.GetType().Name); 22: } 23: } 執行上面的代碼,有注意8,11行分別有兩個Exception,而這時到第一個Catch塊中AggregateException只會捕捉第一個NullReferenceException異常,這是By Design的問題。有個解決方案是這樣的:
1: try 2: { 3: Task t = Task.Factory.StartNew(() => 4: { 5: Task.Factory.StartNew(() => 6: { throw new NullReferenceException(); }, 7: TaskCreationOptions.AttachedToParent); 8: Task.Factory.StartNew(() => 9: { throw new ArgumentException(); }, 10: TaskCreationOptions.AttachedToParent); 11: }); 12: await t.ContinueWith(tsk => { if (tsk.Exception != null) throw tsk.Exception; }); 13: } 14: catch (AggregateException ex) 15: { 16: foreach (var exc in ex.Flatten().InnerExceptions) 17: { 18: Console.WriteLine(exc.GetType().Name); 19: } 20: }

?

注意上面12行代碼,使用了CoutinueWith方法,為了讓代碼更加簡潔了,我們可以寫一個擴展方法:

/// <summary> /// ThrowMultiple /// </summary> /// <param name="t">Task</param> /// <returns>Task type</returns> public static Task ThrowMultiple(this Task t) { return t.ContinueWith(tsk => { if (tsk.Exception != null) throw tsk.Exception; }); } ? /// <summary> /// ThrowMultiple /// </summary> /// <typeparam name="T">Task this</typeparam> /// <param name="t">Task t</param> /// <returns>Task generic</returns> public static Task<T> ThrowMultiple<T>(this Task<T> t) { return t.ContinueWith(tsk => { if (tsk.Exception != null) throw tsk.Exception; return tsk.Result; }); }


然后代碼就是變成這樣了:

1: try 2: { 3: await Task.Factory.StartNew(() => 4: { 5: Task.Factory.StartNew(() => 6: { throw new NullReferenceException(); }, 7: TaskCreationOptions.AttachedToParent); 8: Task.Factory.StartNew(() => 9: { throw new ArgumentException(); }, 10: TaskCreationOptions.AttachedToParent); 11: }).ThrowMultiple(); 12: } 13: catch (AggregateException aex) 14: { 15: // this catch will never be target 16: } 17: catch (Exception ex) 18: { 19: Console.WriteLine("## {0} ##", ex.GetType().Name); 20: }


有看到上面代碼11行的變化為我們擴展方法。就這么簡單,以上代碼在Vs2012下 .net framework 4.5 version 下測試通過,希望對你開發有幫助。

您可能感興趣的文章:

Asp.net MVC 4 異步方法


作者:Petter Liu
出處:http://www.cnblogs.com/wintersun/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
該文章也同時發布在我的獨立博客中-Petter Liu Blog。

總結

以上是生活随笔為你收集整理的Async下处理多个异常的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。