当前位置:编程学习 > asp >>

.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();

我们可以看到运行结果是:

image

上面的代码中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();

看到运行结果:

image

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 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,