我做了一个计算数字的任务,任务将在5秒后收到取消请求,但是在任务取消后我检查了任务的状态。任务状态仍在运行。为什么?示例代码如下:
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);//Request Cancel after 5 seconds
var newTask = Task.Factory.StartNew(state =>
{
try
{
int i = 1;
var token = (System.Threading.CancellationToken)state;
while (true)
{
Console.WriteLine(i);
i++;
Thread.Sleep(1000);
token.ThrowIfCancellationRequested();
}
}
catch
{
}
finally
{
}
}, cts.Token, cts.Token);
try
{
newTask.Wait(10000, cts.Token);
}
catch
{
Console.WriteLine("Catch:"+ newTask.Status);//The status is Running
}
Console.ReadLine();
答案 0 :(得分:3)
该代码存在两个问题:
token.ThrowIfCancellationRequested()
完全按照名称所说,它会引发异常。由于您使用try/catch
块来捕获它,因此您也可以从任务中返回。 "取消后的任务状态"不会成为Faulted
因为框架没有看到异常。Wait
使用相同的取消令牌。这意味着一旦完成5秒,Wait
将被取消,并且将执行catch块。此时任务可能会取消也可能不会取消。您应该做的是摆脱任务正文中的try/catch/finally
,并从致电Wait
:newTask.Wait(10000)
中移除令牌。
完整代码:
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);//Request Cancel after 5 seconds
var newTask = Task.Factory.StartNew(state =>
{
int i = 1;
var token = (System.Threading.CancellationToken)state;
while (true)
{
Console.WriteLine(i);
i++;
Thread.Sleep(1000);
token.ThrowIfCancellationRequested();
}
}, cts.Token, cts.Token);
try
{
newTask.Wait(10000);
}
catch
{
Console.WriteLine("Catch:"+ newTask.Status);
}
LINQpad输出:
1
2
3
4
5
捉:取消
答案 1 :(得分:0)
尝试将状态打印到catch块之外的控制台。在您打印状态时,CancellationPended和Exception抛出,但状态在catch块执行完成后立即更改。