I. 监控Task是否取消
1. 监控CancellationToken的IsCancellationRequested属性并抛出System.OperationCanceledException
如果IsCancellationRequested是true, 系统需要中断task,释放它所使用的资源,同时要抛出OperationCanceledException,注意如果你在代码中不抛出这个异常,task就不会被正确设置状态;同时最好把CancellationToken做为这个异常的一个参数放到此异常中。
1: if (token.IsCancellationRequested)
2: {
3: throw new System.OperationCanceledException(token);
4: }
如果没有资源需要释放,可以把检查IsCancellationRequested和抛出异常合并到一起
1: token.ThrowIfCancellationRequested();
2. 为CancellationToken注册一个delegate, 当CancellationTokenSource.Cancel()被调用的时候,这个委托所代表的方法就会被调用
1: token.Register(() => { Console.WriteLine("I am registered!"); });
这点与回调方法有些类似。
3. 调用CancellationToken.WaitHandle.WaitOne()方法
当CancellationTokenSource.Cancel()被调用的时候,这个方法会被调用。关于WaitHandle属性,我们会在后续章节中介绍。这点与多线程中的回调方法和资源的亲源性有关。
我们可以通过Task的IsCancelled属性来判断一个Task是否被Cancelled了
II. 等待Task
还记得我们在前面一节中提出的并行运行的两个基本问题吧,解决这个问题的方法就是要协调各个Task之间的执行顺序。这一节介绍的内容就是一些基本的协调Task运行的方法
1. 等待一个Task运行完成
task1.Wait()
2. 等待多个Task运行完成
Task.WaitAll(task1,task2)
3. 等待多个Task中的任何一个运行完成
Task.WaitAny(task1,task2)
注意这些上述这些方法都有多个重载版本。
III. Task异常处理
1: try
2: {
3: //tasks
4: }
5: catch (System.AggregateException ex)
6: {
7: foreach (Exception innerEx in ex.InnerExceptions)
8: {
9: //your codes
10: }
11:
12: }
AggregateException是TPL为并行提供的最基本的异常. 开发人员可以使用AggregateException的属性InnerExceptions, 在try块里所有Task抛出的异常都包含在这个集合里。
如果想要为这些异常指定自己的处理方法,开发人员可以使用AggregateException的Handle()方法
如果开发人员在代码里没有处理异常,一旦运行过程中出现异常,.NET Framework会向上抛出异常。开发人员可以使用异常上调策略来控制这些异常,有兴趣的开发人员可以查一下资料看看。
1: try
2: {
3: //tasks
4: }
5: catch (System.AggregateException ex)
6: {
7: ex.Handle((inner) =>
8: {
9: if (inner is OperationCanceledException)
10: {
11: return true;
12: }
13: else
14: {
15: return false;
16: }
17: });
18: }