一起谈.NET技术,.Net 4.0 Parallel 编程(五)Task (中)
2011-09-01 23:46
447 查看
在上篇文章中我们看过了如何创建Task,本篇文章就各种类型Task的使用进行说明。
在每次调用ContinueWith方法时,每次会把上次Task的引用传入进来,以便检测上次Task的状态,比如我们可以使用上次Task的Result属性来获取返回值。上面的代买我们也可以这么写:
我们可以看到运行结果是:
上面的代码中outTask.Wait()表示等待outTask执行完成。
看到运行结果:
Cancellation Task
如何取消一个Task呢,我们通过cancellation的tokens来取消一个Task。在很多Task的Body里面包含循环,我们可以在轮询的时候判断IsCancellationRequested属性是否为True,如果是True的话,就可以停止循环以及释放资源,同时抛出OperationCanceledException异常出来。来看一段示例代码:
Task Continuations
首先我们来看看延续的Task,所谓的延续的Task就是在第一个Task完成后自动启动下一个Task。我们通过ContinueWith方法来创建延续的Task。我们假设有一个接受xml解析的服务,首先从某个地方接受文件,然后解析入库,最后返回回执是否解析正确:[TestMethod] public void TaskParallelPrint() { var ReceiveTask = new Task(() => ReceiveXml()); var ResolveTask = ReceiveTask.ContinueWith<bool>((r) => ResolveXml()); var SendFeedBackTask = ResolveTask.ContinueWith<string>((s) => SendFeedBack(s.Result)); ReceiveTask.Start(); Console.WriteLine(SendFeedBackTask.Result); }
在每次调用ContinueWith方法时,每次会把上次Task的引用传入进来,以便检测上次Task的状态,比如我们可以使用上次Task的Result属性来获取返回值。上面的代买我们也可以这么写:
[TestMethod] public void TaskParallelPrint() { var SendFeedBackTask = Task.Factory.StartNew(() => ReceiveXml()) .ContinueWith<bool>(s => ResolveXml()) .ContinueWith<string>(r => SendFeedBack(r.Result)); Console.WriteLine(SendFeedBackTask.Result); }
Detached Nested Tasks
有些情况下我们需要创建嵌套的Task,嵌套里面又分为分离的和不分离的。其创建的方式很简单,就是在Task的body里面创建一个新的Task。如果新的Task未指定AttachedToParent选项,那么就是分离嵌套的。我们看下面这段代码:var outTask = Task.Factory.StartNew(() => { Console.WriteLine("Outer task beginning..."); var childTask = Task.Factory.StartNew(() => { Thread.SpinWait(3000000); Console.WriteLine("Detached nested task completed."); }); }); outTask.Wait(); Console.WriteLine("Outer task completed."); Console.ReadKey();
我们可以看到运行结果是:
上面的代码中outTask.Wait()表示等待outTask执行完成。
Child Tasks
我们将上面的代码加上TaskCreationOptions选项:var outTask = Task.Factory.StartNew(() => { Console.WriteLine("Outer task beginning..."); var childTask = Task.Factory.StartNew(() => { 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异常出来。来看一段示例代码:
var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; var task = Task.Factory.StartNew(() => { for (var i = 0; i < 10000000; 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 e) { foreach (var v in e.InnerExceptions) Console.WriteLine("msg: " + v.Message); } Console.ReadKey();
总结
本篇文章中我们看过了创建各种不同的Task以及如何取消Task,下篇文章中会就异常处理以及Task Laizy进行说明。相关文章推荐
- .Net 4.0 Parallel 编程(四) Task(上)
- .Net 4.0 Parallel 编程(九)Task中的数据共享(下)
- .Net 4.0 Parallel 编程(六)Task(下)
- .Net 4.0 Parallel 编程(七)Task中的数据共享(上)
- 一起谈.NET技术,.NET 4 并行(多核)编程系列之二 从Task开始
- 一起谈.NET技术,VS2010&.Net 4.0 之并行运算(Parallel)(For、Foreach)
- 一起谈.NET技术,.NET 4.0里异常处理的新机制
- 一起谈.NET技术,VS 2010 和 .NET 4.0 系列之《多定向支持》篇
- 一起谈.NET技术,.NET中通过代理实现面向方面编程(AOP)
- 一起谈.NET技术,VS 2010 和 .NET 4.0 系列之《内置图表控件》篇
- 一起谈.NET技术,VS 2010 和 .NET 4.0 系列之《干净的Web.Config文件 》篇
- 一起谈.NET技术,使用WCF实现SOA面向服务编程——使用AJAX+WCF服务页面开发
- 一起谈.NET技术,ASP.NET 4.0 来了
- 一起谈.NET技术,VS 2010 和 .NET 4.0 系列之《起始项目模板》篇
- 一起谈.NET技术,使用WCF实现SOA面向服务编程——简单的WCF开发实例
- 一起谈.NET技术,VS 2010 和 .NET 4.0 系列之《添加引用对话框的改进》篇
- 一起谈.NET技术,.Net4.0 Parallel编程(四)Task 上
- 一起谈.NET技术,如何让ASP.NET默认的资源编程方式支持非.ResX资源存储
- 一起谈.NET技术,VS 2010 和 .NET 4.0 系列之《VS 2010代码智能提示的改进》篇
- 一起谈.NET技术,谈谈C# 4.0新特性“缺省参数”的实现