1

The idea: create a Task that prints an increasing number of asterisks. When the user presses Enter, the Task prints 10 asterisks and then stops.

The code:

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();
            }
        }
    }
}

The question: why isn't my continuation task executed?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
Maria Ines Parnisari
  • 16,584
  • 9
  • 85
  • 130
  • possible duplicate of [CancellationTokenSource not behaving as expected](http://stackoverflow.com/questions/24346706/cancellationtokensource-not-behaving-as-expected) – i3arnon Sep 08 '14 at 20:27

1 Answers1

5

It isn't being executed because you're not actively cancelling the Task, only checking if a cancellation was requested. Use CancellationToken.ThrowIfCancellationRequested which throws an OperationCanceledException and will transform the Task into a cancelled state or simply throw the exception with the corresponding token:

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

Which is equivalent to:

Task task = Task.Run(() =>
{
      int count = 1;
      while (!token.IsCancellationRequested)
      {
           Console.WriteLine(new string('*', count));
           Thread.Sleep(1000);
           count++;
       }
       throw new OperationCanceledException(token);
 }, token)
Simon Whitehead
  • 63,300
  • 9
  • 114
  • 138
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321