C# 并行编程 Task

1. 创建Task

创建Task的方法有两种,一种是直接创建——new一个出来,一种是通过工厂创建。

        //第一种创建方式,直接实例化
         var task1 = new Task(() =>
         {
            //TODO you code
         });
         task1.Start();

这是最简单的创建方法,可以看到其构造函数是一个Action。

        //第二种创建方式,工厂创建
         var task2 = Task.Factory.StartNew(() =>
         {
            //TODO you code
         });

这种方式通过静态工厂,创建以个Task并运行。

通过构造函数创建的task,必须手动Start,而通过工厂创建的Task直接就启动了。

 

2. Task的简略生命周期(状态):

Created:表示默认初始化任务,但是“工厂创建的”实例直接跳过。

WaitingToRun: 这种状态表示等待任务调度器分配线程给任务执行。

RanToCompletion:任务执行完毕。

 

3. Task的任务控制

Task最吸引人的地方就是他的任务控制了,你可以很好的控制task的执行顺序,让多个task有序的工作。

Task.Wait    就是等待任务执行完成

Task.WaitAll    就是等待所有的任务都执行完成

Task.WaitAny    就是等待任何一个任务完成就继续向下执行

Task.ContinueWith    就是在第一个Task完成后自动启动下一个Task,实现Task的延续

Task的取消  比如我们启动了一个task,出现异常或者用户点击取消等等,我们要取消这个任务,这时我们通过cancellation的tokens来取消一个Task。在很多Task的Body里面包含循环,我们可以在轮询的时候判断IsCancellationRequested属性是否为True,如果是True的话就return.

         var tokenSource = new CancellationTokenSource();
         var token = tokenSource.Token;
         var task = Task.Factory.StartNew(() =>
         {
            for (var i = 0; i < 1000; i++)
            {
               System.Threading.Thread.Sleep(1000);
               if (token.IsCancellationRequested)
               {
                  Console.WriteLine("Abort mission success!");
                  return;
               }
            }
         }, token);
         token.Register(() =>
         {
            Console.WriteLine("Canceled");
         });
         Console.WriteLine("Press enter to cancel task...");
         Console.ReadKey();
         tokenSource.Cancel();
         Console.ReadKey();

这里开启了一个Task,并给token注册了一个方法,输出一条信息,然后执行ReadKey开始等待用户输入,用户点击回车后,执行tokenSource.Cancel方法,取消任务。

 

4. Task的异常处理

     static void Main(string[] args)
      {
         try
         {
            var pTask = Task.Factory.StartNew(() =>
            {
               var cTask = Task.Factory.StartNew(() =>
               {
                  System.Threading.Thread.Sleep(2000);
                  throw new Exception("cTask Error!");
                  Console.WriteLine("Childen task finished!");
               });
               throw new Exception("pTask Error!");
               Console.WriteLine("Parent task finished!");
            });

            pTask.Wait();
         }
         catch (AggregateException ex)
         {
            foreach (Exception inner in ex.InnerExceptions)
            {
               Console.WriteLine(inner.Message);
            }
         }
         Console.WriteLine("Flag");
         Console.Read();
      }
 

这里用了AggregateException,就是异常集合,才能捕获到真正的异常信息。

 

 

 

 

 

*****************************************************
*** No matter how far you go, looking back is also necessary. ***
*****************************************************
posted @ 2019-09-27 15:43  Gangle  阅读(490)  评论(0编辑  收藏  举报