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