C#异步编程详解

2019-12-30 16:13:00王振洲

除了wait等待单个任务外,task还提供了等待多个任务,WaitAny和WaitAll,它阻止调用线程,直到数组中所有的Task对象完成。

取消任务

任务的取消同样使用的是.NET Framework的标准取消操作模式,首先需要创建一个CancellationTokenSource对象,然后在函数中加入参数CancellationToken,将CancellationTokenSource的Token传递给方法,然后调用IsCancellationRequested获取是否已经取消该值进行判断。


static void Main(string[] args)
    {
      Console.WriteLine("开始进行计算");
      // ThreadPool.QueueUserWorkItem(Sum, 10);
      var ctx = new CancellationTokenSource();
      var task = new Task<int>(() => Sum(ctx.Token, 100000));
      task.Start();
      //显示等待获取结果
      //task.Wait(ctx.Token);
      Thread.Sleep(1000);
      ctx.Cancel();
      //调用Result时,等待返回结果
      Console.WriteLine("程序结果为 Sum = {0}", task.Result);
      Console.WriteLine("程序结束");
      Console.ReadLine();
    }
    public static int Sum(CancellationToken cts, object i)
    {
      var sum = 0;    
      for (var j = 0; j <= (int)i; j++)
      {
        if (cts.IsCancellationRequested) return sum;
        Thread.Sleep(50);
        Console.Write("{0} + ", sum);
        sum += j;
      }
      Console.WriteLine(" = {0}", sum);
      return sum;
    }

任务完成后自动启动新任务

实际的开发应用中,经常出现一次任务完成后立刻启动另外一个任务,并且不能够使线程阻塞,在任务尚未完成时调用result会使程序阻塞,无法查看任务的执行进度,TASK提供了一个方法ContinueWith,它不会阻塞任何线程,当第一个任务完成时,会立即启动第二个任务。


static void Main(string[] args)
    {
      Console.WriteLine("开始进行计算");
      // ThreadPool.QueueUserWorkItem(Sum, 10);
      var ctx = new CancellationTokenSource();
      var task = new Task<int>(() => Sum(ctx.Token, 100000));
      task.Start();
      var cwt = task.ContinueWith(p =>
      {
        Console.WriteLine("task result ={0} ",task.Result);
      });
      //显示等待获取结果
      //task.Wait(ctx.Token);
      Thread.Sleep(1000);
      ctx.Cancel();
      //调用Result时,等待返回结果
      Console.WriteLine("程序结果为 Sum = {0}", task.Result);
      Console.WriteLine("程序结束");
      Console.ReadLine();
    }
    public static int Sum(CancellationToken cts, object i)
    {
      var sum = 0;    
      for (var j = 0; j <= (int)i; j++)
      {
        if (cts.IsCancellationRequested) return sum;
        Thread.Sleep(50);
        Console.Write("{0} + ", sum);
        sum += j;
      }
      Console.WriteLine(" = {0}", sum);
      return sum;
    }