Task ThrowAfter(int ms,string message) 2 { 3 await Task.Delay(ms); Exception(message); 5 } DontHandle() 8 { { ); 12 } 13 catch (Exception ex) 14 { } 18 }
以上代码并不能捕获到异常,应为在ThrowAfter抛出异常之前DontHandle已经执行完了。
4.1 异步方法的异常处理异步方法异常的一个较好的处理是使用关键字Await,然后将其放在try中
HandleErrorOne() 2 { { ); 6 } 7 catch (Exception ex) 8 { 9 Console.WriteLine(ex.Message); 10 } 11 }
4.2 多个异步方法的异常处理
StatTwoTasks() 2 { { ); ); 7 } 8 catch (Exception ex) 9 { 10 Console.WriteLine(ex.Message); 11 } 12 }
如上代码并不能捕获全部的异常,原因是因为在第一个异常抛出后程序就进入了catch。解决方法
StatTwoTasksParallel() 2 { { ); ); 7 await Task.WhenAll(t1,t2); 8 } 9 catch (Exception ex) 10 { 11 Console.WriteLine(ex.Message); 12 } 13 }
4.3 AggregateException类
为了得到所有的异常信息,可以将Task.WhenAll返回的结果写到一个Task中,这个任务一直等待所有的任务完成。
ShowAggregateException() 2 { 3 Task taskResult = null; { ); ); 8 await(taskResult= Task.WhenAll(t1, t2)); 9 } 10 catch (Exception ex) 11 { 12 Console.WriteLine(ex.Message); 13 foreach (var item in taskResult.Exception.InnerExceptions) 14 { 15 Console.WriteLine(item.Message); 16 } 17 } 18 }
5取消在某种情况下,后台任务可能运行很长的时间,取消任务就非常有用了。
5.1 开始取消任务1 private CancellationTokenSource cts; Cancle() 3 { 4 if (cts != null) 5 cts.Cancel(); 6 }
CancellationTokenSource 类还支持在指定时间后才取消任务,CancelAfter方法在应该取消的任务后传入一个时间值,单位是ms. 5.2开始框架的特性任务取消CancelTwo() 2 { 3 cts = new CancellationTokenSource(); 4 HttpClient hc = new HttpClient(); , cts.Token); 6 }
5.3取消自定义任务1 await Task.Run(()=> { },cts.Token);
现在用户就可以取消运行时间长的任务了。