在線程執行的地方使用try..catch..捕獲不到異常,在調用Task的Wait()方法或Result屬性處會拋出Task中的異常。
Task中可能會拋出多個異常,應該使用AggregateException捕獲多線程中所有異常。AggregateException是一個集合
但是如果沒有返回結果,或者不想調用Wait()方法,該怎么獲取異常呢?
首先,線程內部不應該出現異常,所以首選處理方式是在Task中使用try..catch..把異常處理掉
如果不可以在內部捕獲,可以使用ContinueWith()方法捕獲異常
1 var t = Task.Run<int>(() =>
2 { 3 throw new Exception("error"); 4 Console.WriteLine("action do do do"); 5 return 1; 6 }).ContinueWith<Task<int>>((t1) => { 7 if (t1 != null && t1.IsFaulted) 8 { 9 Console.WriteLine(t1.Exception.Message); //記錄異常日志 10 } 11 return t1; 12 }).Unwrap<int>();
上面使用起來比較麻煩,添加一個擴展方法:
1 public static Task Catch(this Task task) 2 { 3 return task.ContinueWith<Task>(delegate(Task t) 4 { 5 if (t != null && t.IsFaulted) 6 { 7 AggregateException exception = t.Exception; 8 Trace.TraceError("Catch exception thrown by Task: {0}", new object[] 9 { 10 exception 11 }); 12 } 13 return t; 14 }).Unwrap(); 15 } 16 public static Task<T> Catch<T>(this Task<T> task) 17 { 18 return task.ContinueWith<Task<T>>(delegate(Task<T> t) 19 { 20 if (t != null && t.IsFaulted) 21 { 22 AggregateException exception = t.Exception; 23 Trace.TraceError("Catch<T> exception thrown by Task: {0}", new object[] 24 { 25 exception 26 }); 27 } 28 return t; 29 }).Unwrap<T>(); 30 }