c# 高级编程 21章470页 【任务和并行编程】【取消】

取消

目前,以下技术支持以标准方式取消长时间运行的操作:任务、并发集合类、并行LINQ、其他集中同步机制。

取消,是协作的,它不是强迫的

长时间运行的任务会检查它是否被取消,并响应地返回控制权

支持取消的方法,接收一个CancellationToken参数。

  • 长时间运行的操作,检查取消的方式:
    • IsCancellationRequested属性
    • 取消标记时,使用WaitHandle属性
    • 使用Register方法,接收以下参数:
      • Action:在取消标记时调用
      • ICancelableOperation,实现这个接口的对象的Cancel()方法再执行取消操作室调用

Parallel.For() 的取消

  • ParallelOptions
    • CancellationToken
      • 通过CancellationTokenSource来生成
        • CancellationTokenSource实现了ICancelableOperation接口
          • 因此,可以用CancellationToken注册, Register()方法注册取消操作时的信息
            • 允许用Cancel()方法取消操作
  • Parallel类验证CancellationToken的结果,并取消操作
  • 一旦取消操作,For()就抛出一个OperationCanceledException
        public static void CancelParallelFor()
        {
            Console.WriteLine(nameof(CancelParallelFor));
            var cts = new CancellationTokenSource();
            cts.Token.Register(() => Console.WriteLine("*** token cancelled"));

            // send a cancel after 500 ms
            cts.CancelAfter(500);

            try
            {
                ParallelLoopResult result =
                  Parallel.For(0, 100, new ParallelOptions
                  {
                      CancellationToken = cts.Token,
                  },
                  x =>
                  {
                      Console.WriteLine($"loop {x} started");
                      int sum = 0;
                      for (int i = 0; i < 100; i++)
                      {
                          Task.Delay(2).Wait();
                          sum += i;
                      }
                      Console.WriteLine($"loop {x} finished");
                  });
            }
            catch (OperationCanceledException ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.WriteLine();
        }
复制代码

输出:

CancelParallelFor
loop 0 started
loop 24 started
loop 12 started
loop 36 started
loop 48 started
loop 60 started
loop 72 started
loop 84 started
loop 96 started
*** token cancelled
loop 24 finished
loop 84 finished
loop 0 finished
loop 36 finished
loop 96 finished
loop 12 finished
loop 48 finished
loop 72 finished
loop 60 finished
The operation was canceled.
复制代码

猜你喜欢

转载自juejin.im/post/7078292095940689933