一起谈.NET技术,.Net 4.0 Parallel 编程(五)Task (中)

  在上篇文章中我们看过了如何创建Task,本篇文章就各种类型Task的使用进行说明。

  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进行说明。

时间: 2024-10-23 21:54:35

一起谈.NET技术,.Net 4.0 Parallel 编程(五)Task (中)的相关文章

一起谈.NET技术,.Net4.0 Parallel编程(二)Data Parallelism 中

在上篇文章中看过了使用Parrallel.For.Parael.Foreach在效率上给我们带来的提高.本文就来如何终止循环.线程局部变量 进行说明. Thread-Local Variables 首先我们来看下线程局部变量,是的我们也许一直在想我们如何去定义一个线程局部变量呢.先看段顺序执行的代码: [TestMethod()]public void NormalSequenceTest(){int[] nums = Enumerable.Range(0, 1000000).ToArray()

一起谈.NET技术,.Net4.0 Parallel编程(四)Task 上

在之前的文章中,已经介绍过了Parallel Loop(上.中.下)的相关内容.本篇文章中会就Task基础部分进行些介绍. 初识Task 首先我们来构建一个简单的Task的Demo: static void Main(string[] args){ Task.Factory.StartNew(() => { Console.WriteLine("Hello word!"); }); Console.Read();} 在上面这段代码中我们构建出了一段非常简单的使用Task类的代码,

一起谈.NET技术,.Net4.0 Parallel编程(一)Data Parallelism 上

Parallel.For 首先先写一个普通的循环: private void NormalFor(){for (var i = 0; i < 10000; i++) {for (var j = 0; j < 1000; j++) {for (var k = 0; k < 100; k++) { DoSomething(); } } }} 再看一个并行的For语句: private void ParallelFor(){ Parallel.For(0, 10000, i => {fo

一起谈.NET技术,.Net4.0 Parallel编程(三)Data Parallelism 下

在上篇文章中介绍了如何Break.Stop循环,以及如何定义线程局部变量.在本文中介绍如何在外部去取消循环.以及异常的处理. Cancel 在并行的循环中支持通过传递ParallelOptions参数中的CancellationToken进行取消循环的控制,我们可以CancellationTokenSource实例化之后传递给ParallelOptions对象Cancellation值.下面来看个示例: [TestMethod]public void CancelLoop(){ var sour

.Net4.0 Parallel编程(四)Task 上

在之前的文章中,已经介绍过了Parallel Loop(上.中.下)的相关内容.本篇文章中会就Task基础部分进行些介绍. 初识Task 首先我们来构建一个简单的Task的Demo: static void Main(string[] args) { Task. Factory.StartNew(() => { Console.WriteLine("Hello word!"); }); Console.Read(); } 在上面这段代码中我们构建出了一段非常简单的使用Task类的

.Net4.0 Parallel编程(二)Data Parallelism 中

在上篇文章中看过了使用Parrallel.For.Parael.Foreach在效率上给我们带来的提高.本文就来如何终止循环.线程局部变量 进行说明. Thread-Local Variables 首先我们来看下线程局部变量,是的我们也许一直在想我们如何去定义一个线程局部变量呢.先看段顺序执行的代码: [TestMethod()] public void NormalSequenceTest() { int[] nums = Enumerable.Range(0, 1000000).ToArra

一起谈.NET技术,MVC2.0本地化(另类解决方案)&amp;lt;下&amp;gt;

本文是对MVC2.0本地化(另类解决方案)上这篇文章内介绍的MVC2.0本地化功能进行加强.细化的结尾篇.如果存在不足的地方,希望您指出. 如何对上篇文章进行加强以及细化呢?主要从以下三点开始. 1.根据用户浏览器自动语言判断,同时也可由用户自定义站点语言. 2.多语言加入,类似resource文件,可以有多个语言资源库. 3.全局本地化,可以本地化非页面内容,比如为台异步到前台的json数据本地化等. 主要步骤如下: 一.根据用户浏览器自动语言判断,同时也可由用户自定义站点语言 这个实现思路为

一起谈.NET技术,.NET4.0 之 Dynamic VS Reflection 效率

在我先前的文章中,不断的推广.NET4.0新特性.特别是.NET4.0 Dynamic 这个新特性.随之而来的问题也出现了-Dynamic 执行效率如何? 我们做开发的不光需要代码简洁,能够希望自己能够写出好的架构.还有一点非常重要的就是,我们的写出来的代码效率.撇开Dynamic在.net4.0中的实现原理.本篇只考虑dynamic 的效率比起使用反射到底是快还是慢?难道.NET为引入了dynamic这个新鲜事物降低了我们的程序效率?有网友指出评论一个特性或者方法的效率如何,唯一的判定标准就是

一起谈.NET技术,NHibernate3.0剖析:Query篇之NHibernate.Linq标准查询

系列引入 NHibernate3.0剖析系列分别从Configuration篇.Mapping篇.Query篇.Session策略篇.应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成,基于NHibernte3.0版本.如果你还不熟悉NHibernate,可以快速阅读NHibernate之旅系列文章导航系列入门,如果你已经在用NHibernate了,那么请跟上NHibernate3.0剖析系列吧. NHibernate专题:http://kb.cnblogs.com