zoukankan      html  css  js  c++  java
  • 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. ***
    *****************************************************
  • 相关阅读:
    51nod 1127 最短的包含字符串
    hdu 2197 本原串
    hdu 2160 母猪的故事
    hdu 2594 Simpsons’ Hidden Talents
    自旋锁原理及java自旋锁
    Java中CAS详解
    dump相关
    多线程设置线程超时思路
    kafka遗忘点
    Java 和 HTTP 的那些事(四) HTTPS 和 证书(转)
  • 原文地址:https://www.cnblogs.com/gangle/p/11598364.html
Copyright © 2011-2022 走看看