How to cancel a Task using CancellationToken?

10,796

You're swallowing the exception, thus the task is flagged as finished as you actually handle the exception and it doesn't propagate outwards.

Instead, don't catch the exception inside the delegate, catch it outside:

void Main()
{
    CancellationTokenSource src = new CancellationTokenSource();
    CancellationToken ct = src.Token;
    ct.Register(() => Console.WriteLine("Abbruch des Tasks"));

    Task t = Task.Run(() =>
    {
        System.Threading.Thread.Sleep(1000);
        ct.ThrowIfCancellationRequested();
    }, ct);

    src.Cancel();
    try
    {
        t.Wait();
    }
    catch (AggregateException e)
    {
        // Don't actually use an empty catch clause, this is
        // for the sake of demonstration.
    }

    Console.WriteLine("Canceled: {0} . Finished: {1} . Error: {2}",
                       t.IsCanceled, t.IsCompleted, t.IsFaulted);
}
Share:
10,796
Netherstorm
Author by

Netherstorm

Updated on June 05, 2022

Comments

  • Netherstorm
    Netherstorm almost 2 years

    So I've this code:

    //CancelationToken
    CancellationTokenSource src = new CancellationTokenSource();
    CancellationToken ct = src.Token;
    ct.Register(() => Console.WriteLine("Abbruch des Tasks"));
    //Task
    Task t = new Task(() =>
    {
        System.Threading.Thread.Sleep(1000);
        if (ct.IsCancellationRequested)
        {
            try
            {
                //Throw
                ct.ThrowIfCancellationRequested();                        
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine(
                    "ThrowIfCancellationRequested() liefert eben eine Exception");
            }
        }             
    
    }, ct);
    //Run Task and Cancel
    t.Start();
    src.CancelAfter(350);
    t.Wait();
    
    // Get Information
    Console.WriteLine("Canceled: {0} . Finished: {1} . Error: {2}",
                        t.IsCanceled, t.IsCompleted, t.IsFaulted);
    

    So in this case I canceled my Task but my output in the end is: "Canceled: False . Finished: True . Error: False"

    In my opinion it should be "Canceled:True . Finished:False". Why do I get this result? Because I try to catch the exception?

    I've tried it without the try - catch block, but then my program stops because of the OperationCanceledException. Can somebody help me?