我试图在取消下面的任务
上运行一个简单的例子CancellationTokenSource tokenSource2 = new CancellationTokenSource();
CancellationToken token2 = tokenSource2.Token;
Task task2 = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
token2.ThrowIfCancellationRequested();
Thread.Sleep(100);
Console.WriteLine("Task 2 - Int value {0}", i);
}
}, token2);
task2.Start();
Console.WriteLine("Press any key to cancel the task");
Console.ReadLine();
tokenSource2.Cancel();
Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled);
我预计Console.WriteLine("Task 2 cancelled? {0}", task2.IsCanceled);
会打印**"Task 2 cancelled? True"**
,但会打印“False”。
编辑:确保在调用取消请求之前未完成任务。我添加了Console.ReadLine()
。
答案 0 :(得分:5)
首先,也许您误解了IsCanceled
的含义?这并不意味着“此Task
正在等待取消,因此它应该很快完成”,这意味着“此Task
已取消,现在已完成”。
如果你没有误解,请考虑事件的顺序是什么。会发生什么:
ThrowIfCancellationRequested()
被调用,但令牌尚未取消,所以它不会抛出。Thread.Sleep()
,因此运行Task
的线程会休眠。Cancel()
被召唤。IsCanceled
已经过检查。 Task
中的代码没有机会意识到令牌已被取消,因此它仍在运行,因此IsCanceled
会返回false
。ThrowIfCancellationRequested()
,此时它会抛出,实际上会取消Task
。这就是ISCanceled
向您返回false
的原因。如果您希望它返回true
,则可以在检查Thread.Sleep(150)
之前添加IsCanceled
之类的内容,或者更好的是,等待Task
完成。
答案 1 :(得分:2)
任务在您致电取消之前结束,请看下面的内容,这可能有助于更多地了解如何解决您的问题
通过阅读http://social.msdn.microsoft.com/Forums/da-DK/parallelextensions/thread/9f88132a-f8bd-4885-ab63-645d7b6c2127,似乎该令牌用于在“真正”启动任务之前取消任务,但是在排队之后。
阅读这是一种取消计划发生但尚未开始的任务的方法。一旦任务运行,取消它的唯一方法是通过您自己在方法中的检查合作。如果没有这个,你必须始终启动任务,然后在内部进行检查,这将增加许多额外的,不必要的开销
答案 2 :(得分:2)
这不是答案,但在评论中写的时间太长
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;
Task task = new Task(() =>
{
for (int i = 0; i < int.MaxValue; i++)
{
cancellationToken.ThrowIfCancellationRequested();
Console.WriteLine("Task 2 - Int value {0}", i);
}
}, cancellationToken);
task.Start();
cancellationTokenSource.Cancel();
try
{
task.Wait();
}
catch (AggregateException ae)
{
if(ae.InnerExceptions.Single() is TaskCanceledException)
Console.WriteLine("Caught TaskCanceledException");
else
Console.WriteLine("Did not catch canceled");
}
Console.WriteLine("Task 2 cancelled? {0}", task.IsCanceled);
patterns for handling exceptions using tasks
可以很好地阅读。