GPS平台,网站建设,软件开发,系统运维,找森大网络科技!
http://cnsendnet.taobao.com
来自森大科技官方博客http://www.cnsendblog.com/index.php/?p=435
一:任务的优势
ThreadPool相比线程来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便,比如:
1: ThreadPool不支持线程的取消,完成,失败通知等交互性操作,
2: ThreadPool不支持线程执行的先后次序;
以往,如果开发者要实现上述功能,需要完成很多额外的工作,现在,FCL中提供了一个功能更强大的概念:Task.Task在线程池的基础上进行了优化,并提供了更多的API。在FCL4.0中,如果我们要编写多线程程序,任务显然已经优于传统的方式。
以下是一个简单的任务示例:
<代码> staticvoid Main (string [] args) { 任务t=新任务(()=比; { Console.WriteLine(“任务开始工作……”);//模拟工作过程 thread . sleep (5000); }); t.Start (); t.ContinueWith((任务)=比; { Console.WriteLine(“任务完成,完成时候的状态为:"); 控制台。WriteLine (“IsCanceled={0} \ tIsCompleted={1} \ tIsFaulted={2}”,任务。IsCanceled,任务。IsCompleted task.IsFaulted); }); Console.ReadKey (); }代码>
二:任务的完成状态
任务任务有这样一些属性,让我们查询任务完成时的状态:
1: IsCanceled,因为被取消而完成;
2: IsCompleted,成功完成;
3: IsFaulted,因为发生异常而完成
需要注意的是,任务并没有提供回调事件来通知完成(像BackgroundWorker一样),它通过启用一个新任务的方式来完成类似的功能.ContinueWith方法可以在一个任务完成的时候发起一个新任务,这种方式天然就支持了任务的完成通知:我们可以在新任务中获取原任务的结果值。
<代码>下面是一个稍微复杂一点的例子,同时支持完成通知,取消,获取任务返回值等功能:代码>
<代码> staticvoid Main (string [] args) { 时候触发的时候触发cts=new (); Taskt=新Task (()=比;添加(cts.Token) cts.Token); t.Start (); t.ContinueWith (TaskEnded);//等待按下任意一个键取消任务 Console.ReadKey (); cts.Cancel (); Console.ReadKey (); } staticvoid TaskEnded (Task 任务) { Console.WriteLine(“任务完成,完成时候的状态为:"); 控制台。WriteLine (“IsCanceled={0} \ tIsCompleted={1} \ tIsFaulted={2}”,任务。IsCanceled,任务。IsCompleted task.IsFaulted); 控制台。WriteLine(“任务的返回值为:{0}”,task.Result); } staticint Add (CancellationToken ct) { Console.WriteLine(“任务开始……”); int结果=0; 而(! ct.IsCancellationRequested) { 结果+ +; thread . sleep (1000); } 返回结果; }代码>
在任务开始后大概3秒钟的时候按下键盘,会得到如下的输出:
任务开始……
任务完成,完成时候的状态为:
IsCanceled=False IsCompleted=True IsFaulted=False
任务的返回值为:3
你也许会奇怪,我们的任务是通过取消的方式处理,为什么完成的状态IsCanceled那一栏还是假的。这是因为在工作任务中,我们对于IsCancellationRequested进行了业务逻辑上的处理,并没有通过ThrowIfCancellationRequested方法进行处理。如果采用后者的方式,如下:
<代码> staticvoid Main (string [] args) { 时候触发的时候触发cts=new (); Taskt=新Task (()=比;AddCancleByThrow (cts.Token) cts.Token); t.Start (); t.ContinueWith (TaskEndedByCatch);//等待按下任意一个键取消任务 Console.ReadKey (); cts.Cancel (); Console.ReadKey (); } staticvoid TaskEndedByCatch (Task 任务) { Console.WriteLine(“任务完成,完成时候的状态为:"); 控制台。WriteLine (“IsCanceled={0} \ tIsCompleted={1} \ tIsFaulted={2}”,任务。IsCanceled,任务。IsCompleted task.IsFaulted); 试一试 { 控制台。WriteLine(“任务的返回值为:{0}”,task.Result); } 抓住(AggregateException e) { e.Handle ((err)=比;犯错是OperationCanceledException); } } staticint AddCancleByThrow (CancellationToken ct) { Console.WriteLine(“任务开始……”); int结果=0; 而(真) { ct.ThrowIfCancellationRequested (); 结果+ +; thread . sleep (1000); } 返回结果; } 使用任务代替ThreadPool和线程