Learner
Learner

Reputation: 1542

Task Status when cancelled

I have written following code:

CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;

int i = 0;
Console.WriteLine("Calling from Main Thread {0}", System.Threading.Thread.CurrentThread.ManagedThreadId);

Task t1 = new Task(() =>
{
    while (true)
    {
        try
        {
            token.ThrowIfCancellationRequested();
        }

        catch (OperationCanceledException)
        {
            Console.WriteLine("Task1 cancel detected");
            break;
        }

        Console.WriteLine("Task1: Printing: {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, i++);
    }
}, token);

Task t2 = new Task(() =>
{
    while (true)
    {
        try
        {
            token.ThrowIfCancellationRequested();
        }

        catch (OperationCanceledException)
        {
            Console.WriteLine("Task2 cancel detected");
            break;
        }

        Console.WriteLine("Task2: Printing: {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, i++);
    }
});

t1.Start();
t2.Start();
Thread.Sleep(100);
tokenSource.Cancel();

t1.Wait();//wait for thread to completes its execution
t2.Wait();//wait for thread to completes its execution
Console.WriteLine("Task1 Status:{0}", t1.Status);
Console.WriteLine("Task2 Status:{0}", t1.Status);

Here i am cancelling the task then also the status shows RanToCompletion but if i remove wait on both the tasks , then it shows me canceled status...

as i am cancelling the task, i am expecting the canceled status in any case...

EDIT : From MSDN By throwing a OperationCanceledException and passing it the token on which cancellation was requested. The preferred way to do this is to use the ThrowIfCancellationRequested method. A task that is canceled in this way transitions to the Canceled state, which the calling code can use to verify that the task responded to its cancellation request.

If you do not use a Wait or WaitAll method to wait for the task, then the task just sets its status to Canceled.

Upvotes: 3

Views: 4296

Answers (1)

Zaid Masud
Zaid Masud

Reputation: 13463

As you are catching the OperationCanceledException and breaking out of the while loop, the task is ending gracefully and the task status will be RanToCompletion.

In order to get a Canceled status, you will need to either rethrow the OperationCanceledException or not catch it at all.

According to MSDN the Task Status will be Canceled when:

The task acknowledged cancellation by throwing an OperationCanceledException with its own CancellationToken while the token was in signaled state, or the task's CancellationToken was already signaled before the task started executing. For more information, see Task Cancellation.

Since you have swallowed the exception in your source code, the Task Status is going to be RanToCompletion.

To answer your question about why the Status is Canceled when you remove the wait, it is probably because the exception hasn't been caught yet and the cancellation status has been checked at an earlier time. This behaviour should not be considered reliable and reproducible.

Upvotes: 6

Related Questions