生活随笔
收集整理的這篇文章主要介紹了
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下处理多个异常 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。