Task.ContinueWith not working with OnlyOnCanceled

In Microsoft Help 70-483 on using the CancellationToken, the first way to cancel with a signal is to throw an exception, and then it introduces the second:

Instead of catching an exception, you can also add a continuation. A task that runs only when the task is canceled. In this Task, you have access to the exception that has been thrown, and you can choose to handle it if appropriate. Listing 1-44 shows what a continuation task would look like.

Here is a list of 1-44:

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

And this is my full code of the main method:

static void Main(string[] args)
{
    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    var 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);

    Console.ReadLine();
    cancellationTokenSource.Cancel();
    task.Wait();

    Console.ReadLine();
}

, , , Enter, ( AggregationException) Main task.Wait(). , , ( ). -, ? try-catch?

+4
3

, , , :

static void Main(string[] args)
{
    CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
    var token = cancellationTokenSource.Token;

    Task task = Task.Run(() =>
    {
        while (!token.IsCancellationRequested)
        {
            Console.Write("*");
            Thread.Sleep(1000);
        }
    }, token).ContinueWith((t) =>
    {                                                     //  THIS
        t.Exception.Handle((e) => true);                  //  ISN'T
        Console.WriteLine("You have canceled the task");  //  EXECUTING
    }, TaskContinuationOptions.OnlyOnCanceled);

    Console.ReadLine();
    cancellationTokenSource.Cancel();
    task.Wait();

    Console.ReadLine();
}

, token.ThrowIfCancellationRequested() :

        Task task = Task.Run(() =>
        {
            while (true)
            {
                token.ThrowIfCancellationRequested();  // <-- NOTICE
                Console.Write("*");
                Thread.Sleep(1000);
            }
        }, token).ContinueWith((t) =>
        {
            Console.WriteLine("From Continuation: " + t.Status);

            Console.WriteLine("You have canceled the task");
        }, TaskContinuationOptions.OnlyOnCanceled);

// OUTPUT:
// ***
// From Continuation: Canceled
// You have canceled the task

, task.Status Canceled. , task.Status Canceled:

        Task task = Task.Run(() =>
        {
            while (!token.IsCancellationRequested)
            {
                Console.Write("*");
                Thread.Sleep(1000);
            }
        }, token).ContinueWith((t) =>
        {
            Console.WriteLine("From Continuation: " + t.Status);

            Console.WriteLine("You have canceled the task");
        }, TaskContinuationOptions.OnlyOnCanceled);

// OUTPUT:
// AggregationException

, . , OnlyOnCanceled:

        Task task = Task.Run(() =>
        {
            while (!token.IsCancellationRequested)
            {
                Console.Write("*");
                Thread.Sleep(1000);
            }
        }, token).ContinueWith((t) =>
        {
            Console.WriteLine("From Continuation: " + t.Status);
            Console.WriteLine("You have NOT canceled the task");

        });   // <-- OnlyOnCanceled is gone!

// OUTPUT:
// ***
// From Continuation: RanToCompletion
// You have NOT canceled the task
// (no AggregationException thrown)

, .Cancel() task.Status RanToCompletion. , AggregationException. , .Cancel() Canceled.


.Cancel() .ThrowIfCancellationRequested() , AggregationException . MSDN:

Task Task, , System.Threading.Tasks.TaskCanceledException ( AggregateException). , , . Exception null.

:

1-44 - .

t.Exception... , " task Exception null" . 1-44. , :

  • . OnlyOnCanceled .
  • , OnlyOnCanceled , AggregationException Task.Wait()

: , , , , .

+6

, cancellationTokenSource.Cancel(), TaskStatus.RanToCompletion, TaskStatus.Canceled. , TaskContinuationOptions.OnlyOnCanceled TaskContinuationOptions.OnlyOnRanToCompletion

" " MSDN .

:

 CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
var 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.OnlyOnRanToCompletion);

Console.ReadLine();
cancellationTokenSource.Cancel();

try
    {
        task.Wait();
    }
catch (AggregateException e)
    {
        foreach (var v in e.InnerExceptions)
            Console.WriteLine(e.Message + " " + v.Message);
    }
Console.ReadLine();
+2

:

        Task task = Task.Run(() =>
        {
            while (true) {
                token.ThrowIfCancellationRequested();
                Console.Write("*");
                Thread.Sleep(1000);
            }
        }, token).ContinueWith((t) =>
        {
            //t.Exception.Handle((e) => true); //there is no exception
            Console.WriteLine("You have canceled the task");
        }, TaskContinuationOptions.OnlyOnCanceled);
0

Source: https://habr.com/ru/post/1611843/


All Articles