http://www.cnblogs.com/Henllyee/archive/2011/06/06/net_parallel_programing.html
http://www.cnblogs.com/dajiang02/archive/2012/02/08/2342198.html
在上篇文章中我们看过了如何创建Task,本篇文章就各种类型Task的使用进行说明。
Task Continuations
首先我们来看看延续的Task,所谓的延续的Task就是在第一个Task完成后自动启动下一个Task。我们通过ContinueWith方法来创建延续的Task。我们假设有一个接受xml解析的服务,首先从某个地方接受文件,然后解析入库,最后返回回执是否解析正确:
1 2 3 4 5 6 7 8 9 | [TestMethod] public void TaskParallelPrint() { var ReceiveTask = new Task(() => ReceiveXml()); var ResolveTask = bool >((r) => var SendFeedBackTask string >((s) => ReceiveTask.Start(); Console.WriteLine(SendFeedBackTask.Result); } |
在每次调用ContinueWith方法时,每次会把上次Task的引用传入进来,以便检测上次Task的状态,比如我们可以使用上次Task的Result属性来获取返回值。上面的代买我们也可以这么写:
1 2 3 4 5 6 7 8 | [TestMethod] public void TaskParallelPrint() { var SendFeedBackTask .ContinueWith< bool >(s => .ContinueWith< string >(r => Console.WriteLine(SendFeedBackTask.Result); } |
Detached Nested Tasks
有些情况下我们需要创建嵌套的Task,嵌套里面又分为分离的和不分离的。其创建的方式很简单,就是在Task的body里面创建一个新的Task。如果新的Task未指定AttachedToParent选项,那么就是分离嵌套的。我们看下面这段代码:
1 2 3 4 5 6 7 8 9 10 11 12 | var outTask = { Console.WriteLine( "Outer task beginning..." ); var childTask = { Thread.SpinWait(3000000); Console.WriteLine( "Detached nested task completed." ); }); }); outTask.Wait(); Console.WriteLine( "Outer task completed." ); Console.ReadKey(); |
我们可以看到运行结果是:
上面的代码中outTask.Wait()表示等待outTask执行完成。
Child Tasks
我们将上面的代码加上TaskCreationOptions选项:
1 2 3 4 5 6 7 8 9 10 11 12 | var outTask = { Console.WriteLine( "Outer task beginning..." ); var childTask = { Thread.SpinWait(3000000); Console.WriteLine( "Detached nested task completed." ); },TaskCreationOptions.AttachedToParent); }); outTask.Wait(); Console.WriteLine( "Outer task completed." ); Console.ReadKey(); |
看到运行结果:
Cancellation Task
如何取消一个Task呢,我们通过cancellation的tokens来取消一个Task。在很多Task的Body里面包含循环,我们可以在轮询的时候判断IsCancellationRequested属性是否为True,如果是True的话,就可以停止循环以及释放资源,同时抛出OperationCanceledException异常出来。来看一段示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | var tokenSource new CancellationTokenSource(); var token = var task = { for (var i = 0; i < { if (token.IsCancellationRequested) { Console.WriteLine( "Task cacel started..." ); throw new OperationCanceledException(token); } } },token); token.Register(() => { Console.WriteLine( "Canceled" ); }); Console.WriteLine( "Press enter again to cancel task" ); Console.ReadKey(); tokenSource.Cancel(); try { task.Wait(); } catch (AggregateException { foreach (var v in e.InnerExceptions) Console.WriteLine( "msg: " + v.Message); } Console.ReadKey(); |