My question is based on the answer to this question.
Let's say we have the following code:
class Program
{
static void Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
Task<Int32> t = Task.Run(() => Sum(cts.Token, 100000));
// make sure the the task run first before
Thread.Sleep(500);
cancellation request occurs
cts.Cancel();
var status = t.Status; // status is "Faulted"
Console.ReadLine();
}
static Int32 Sum(CancellationToken ct, Int32 n)
{
Int32 sum = 0;
for (; n > 0; n--)
{
// throws
ct.ThrowIfCancellationRequested();
OperationCanceledException if cancellation request occurs
checked { sum += n; }
}
return sum;
}
}
We can see that t
's status is Faulted
which is good.
According to the answer to the question, when we pass the token into task's constructor or Run's parameter, t
's status should be "Canceled" because
when the task sees that
OperationCanceledException
, it checks whether theOperationCanceledException
's token matches the Task's token. If it does, that exception is viewed as an acknowledgement of cooperative cancellation and the Task transitions to the Canceled state (rather than the Faulted state)
but even if we pass the token as
class Program
{
static void Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
// pass the token into Run() method as the second parameter
Task<Int32> t = Task.Run(() => Sum(cts.Token, 100000), cts.Token);
Thread.Sleep(500);
cts.Cancel();
// status is still "Faulted", not "Canceled"
var status = t.Status;
Console.ReadLine();
}
//...
}
t
's status is still Faulted
not Canceled
, so did I misunderstand the answer to the question or did I do something wrong in the code?