取消任务时,不执行继续任务

时间:2014-09-08 01:44:38

标签: c# .net task-parallel-library task

想法:创建一个Task,打印越来越多的星号。当用户按下Enter时,Task会打印10个星号,然后停止。

代码

namespace CancellingLongRunningTasks
{
    using System;
    using System.Threading;
    using System.Threading.Tasks;

    class Program
    {
        static void Main()
        {
            var cancellationTokenSource = new CancellationTokenSource();
            var token = cancellationTokenSource.Token;

            Task task = Task.Run(() =>
            {
                int count = 1;
                while (!token.IsCancellationRequested)
                {
                    Console.WriteLine(new string('*', count));
                    Thread.Sleep(1000);
                    count++;
                }
            }, token).ContinueWith(
                parent =>
                {
                    var count = 10;
                    while (count > 0)
                    {
                        Console.WriteLine(new string('*', count));
                        Thread.Sleep(1000);
                        count--;
                    }
                }, TaskContinuationOptions.OnlyOnCanceled);

            Console.WriteLine("Press enter to stop the task.");

            if (Console.ReadLine().Contains(Environment.NewLine))
            {
                cancellationTokenSource.Cancel();
                task.Wait();
            }
        }
    }
}

问题:为什么我的继续执行任务没有执行?

1 个答案:

答案 0 :(得分:5)

它没有被执行,因为您没有主动取消Task,只检查是否请求取消。使用引发OperationCanceledException的{​​{3}}并将Task转换为已取消状态,或者只是使用相应的令牌抛出异常:

Task task = Task.Run(() =>
{
      int count = 1;
      while (!token.IsCancellationRequested)
      {
           Console.WriteLine(new string('*', count));
           Thread.Sleep(1000);
           count++;
       }
       token.ThrowIfCancellationRequested();
 }, token)

相当于:

Task task = Task.Run(() =>
{
      int count = 1;
      while (!token.IsCancellationRequested)
      {
           Console.WriteLine(new string('*', count));
           Thread.Sleep(1000);
           count++;
       }
       throw new OperationCanceledException(token);
 }, token)