locked
Customize a task cancellation message RRS feed

  • Question

  • I want to customize a task cancellation message rather than the default one "A task was canceled".

    My code:

            static void Main(string[] args)
            {
                CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
                CancellationToken token = cancellationTokenSource.Token;
                Task task = Task.Run(() =>
                {
                    while (!token.IsCancellationRequested)
                    {
                        Console.Write('*');
                        Thread.Sleep(1000);
                    }
                   
                }, token).ContinueWith((t)=>
                    {
                        t.Exception.Handle((e)=>true);
                        Console.WriteLine("You have canceled the task");
                    }, TaskContinuationOptions.OnlyOnCanceled); 
                //token.ThrowIfCancellationRequested();
                try
                {
                    Console.WriteLine("Press enter to stop the task");
                    Console.ReadLine();
                    cancellationTokenSource.Cancel();
                    //task.Wait();
                }
                catch (AggregateException e)
                {
                    Console.WriteLine(e.InnerExceptions[0].Message);
                }
                Console.WriteLine("Press enter to end the application");
                Console.ReadLine();
            }
    The expected task cancellation message is
    You have canceled the task
    My code is not generating it, thanks for help.

    Tuesday, January 6, 2015 6:59 PM

Answers

  • My code? You mean your code. The reason why the "Press enter to end the application" appears before the "You have canceled the task" has nothing do with the fact that the ContinueWith method was never executed which was your original question/issue.

    You must wait for the task to complete execution by calling its Wait method before you terminate the application:

    static void Main(string[] args) {
          CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
          CancellationToken token = cancellationTokenSource.Token;
          Task task = Task.Run(() =>
          {
            while (true) {
              token.ThrowIfCancellationRequested();
              Console.Write('*');
              Thread.Sleep(1000);
            }
    
          }, token).ContinueWith((t) =>
          {
            Console.WriteLine("You have canceled the task");
          }, TaskContinuationOptions.OnlyOnCanceled);
          //token.ThrowIfCancellationRequested();
          try {
            Console.WriteLine("Press enter to stop the task");
            Console.ReadLine();
            cancellationTokenSource.Cancel();
            //task.Wait();
          }
          catch (AggregateException e) {
            Console.WriteLine(e.InnerExceptions[0].Message);
          }
          task.Wait();
          Console.WriteLine("Press enter to end the application");
          Console.ReadLine();
        }
    

    Please remember to close the thread by marking all helpful posts as answer.

     

     

    • Marked as answer by ardmore Wednesday, January 7, 2015 1:40 PM
    Wednesday, January 7, 2015 9:19 AM

All replies

  • Your ContinueWith method is never invoked. If you specify the TaskContinuationOptions.OnlyOnCanceled option you should call the token's ThrowIfCancellationRequested() instead of just breaking out of the while loop:

    while (true)
                    {
                        token.ThrowIfCancellationRequested();
                        Console.Write('*');
                        Thread.Sleep(1000);
                    }

    Second, you are getting an exception in the ContinueWith method because the Exception property is NULL. There will be no exception to handle when specifying the TaskContinuationOptions.OnlyOnCanceled option:

    ContinueWith((t) =>
                {
                    Console.WriteLine("You have canceled the task");
                }, TaskContinuationOptions.OnlyOnCanceled);
    

    Please remember to mark helpful posts as answer and/or helpful.
    Tuesday, January 6, 2015 7:25 PM
  • I tried your code, the message was displayed after "Press enter to end the application". It is supposed before it. Please double check your code.
    Tuesday, January 6, 2015 8:28 PM
  • My code? You mean your code. The reason why the "Press enter to end the application" appears before the "You have canceled the task" has nothing do with the fact that the ContinueWith method was never executed which was your original question/issue.

    You must wait for the task to complete execution by calling its Wait method before you terminate the application:

    static void Main(string[] args) {
          CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
          CancellationToken token = cancellationTokenSource.Token;
          Task task = Task.Run(() =>
          {
            while (true) {
              token.ThrowIfCancellationRequested();
              Console.Write('*');
              Thread.Sleep(1000);
            }
    
          }, token).ContinueWith((t) =>
          {
            Console.WriteLine("You have canceled the task");
          }, TaskContinuationOptions.OnlyOnCanceled);
          //token.ThrowIfCancellationRequested();
          try {
            Console.WriteLine("Press enter to stop the task");
            Console.ReadLine();
            cancellationTokenSource.Cancel();
            //task.Wait();
          }
          catch (AggregateException e) {
            Console.WriteLine(e.InnerExceptions[0].Message);
          }
          task.Wait();
          Console.WriteLine("Press enter to end the application");
          Console.ReadLine();
        }
    

    Please remember to close the thread by marking all helpful posts as answer.

     

     

    • Marked as answer by ardmore Wednesday, January 7, 2015 1:40 PM
    Wednesday, January 7, 2015 9:19 AM