下面是一个示例代码,它创建一个模拟长时间运行进程的新任务。任务中没有任何内容,只关注取消功能。我使用取消令牌取消任务,代码正常工作对我好。
CancellationTokenSource CTS= new CancellationTokenSource();
Task<Boolean> PTask = new Task<Boolean>(() =>
{
while (true)
{
if (!CTS.Token.IsCancellationRequested)
{
Thread.Sleep(5000);
}
else{Console.WriteLine("Thread Cancelled");break;}
}
return true;
}, CTS.Token, TaskCreationOptions.None);
PTask.Start();
Console.WriteLine("Hit Enter to cancel the Secondary thread you have started");
Console.ReadLine();
CTS.Cancel();
System.Console.WriteLine(PTask.Result);
}
}
但是我无法理解的是将令牌参数(CTS.Token)传递给任务构造函数。传递参数的实际用途是什么,即使我没有传递令牌也可以实际取消任务到构造函数。
下面是一个稍微修改过的版本,没有令牌参数。
CancellationTokenSource CTS= new CancellationTokenSource();
Task<Boolean> PTask = new Task<Boolean>(() =>
{
while (true)
{
if (!CTS.Token.IsCancellationRequested)
{
Thread.Sleep(5000);
}
else
{
Console.WriteLine("Thread Cancelled");
break;
}
};
答案 0 :(得分:35)
更新: 以下msdn问题描述了原因:
将令牌传递到StartNew会将令牌与任务相关联。 这有两个主要好处:
如果令牌已取消 在任务开始执行之前请求,任务不会 执行。它不会立即过渡到Running 过渡到已取消。这样可以避免运行任务的成本 无论如何它都会被取消。
- 醇>
如果身体的 任务还监视取消令牌并抛出一个 包含该令牌的OperationCanceledException(这是什么
ThrowIfCancellationRequested
确实),然后当任务看到OCE时, 它检查OCE的令牌是否与Task的令牌匹配。如果它 是的,该例外被视为对合作的承认 取消和任务转换到已取消状态(相反 而不是故障状态。)