我相信我会在下面创建并立即取消任务。但是,运行以下代码时,您会注意到它永远旋转。是什么赋予了?为什么没有附加src.Token
会导致取消?
CancellationTokenSource src = new CancellationTokenSource();
Task t = Task.Run(()=>
{
while (true)
{
Thread.Sleep(100);
}
},
src.Token);
Thread.Sleep(1000);
src.Cancel();
t.Wait();
答案 0 :(得分:3)
在您的代码Task.Run
中,只有在任务执行开始之前令牌已被取消的情况下,才会被取消:
CancellationTokenSource src = new CancellationTokenSource();
src.Cancel();
Task t = Task.Run(()=>
{
while (true)
{
Thread.Sleep(100);
}
},
src.Token);
Thread.Sleep(1000);
t.Wait();
您可以在the official documentation
中了解有关此情况的更多信息另一种方法是将取消令牌传递给Wait
方法:
CancellationTokenSource src = new CancellationTokenSource();
Task t = Task.Run(()=> {while (true) { Thread.Sleep(100); } },src.Token);
Thread.Sleep(1000);
src.Cancel();
t.Wait(src.Token);
在这种情况下,其行为与Task.Run
完全相同:“如果在任务完成前取消了取消令牌,则等待会终止。” (c)docs.microsoft.com
处理取消的正确方法是在长时间运行的任务的每次迭代中检查令牌状态:
CancellationTokenSource src = new CancellationTokenSource();
Task t = Task.Run(() =>
{
while (true)
{
Thread.Sleep(100);
src.Token.ThrowIfCancellationRequested();
}
}, src.Token);
Thread.Sleep(1000);
src.Cancel();
t.Wait();