我试着运行一个简单的示例,说明取消以下任务的情况。
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()。
发布于 2012-12-15 22:34:13
首先,也许你误解了IsCanceled的意思?它并不意味着“这个Task正在等待取消,所以它应该很快完成”,它意味着“这个Task已经被取消了,它现在已经完成了”。
如果你没有误解这一点,那就想想事件的顺序到底是什么。所发生的事情是:
ThrowIfCancellationRequested()被调用,但是令牌还没有被取消,所以它不会抛出。Thread.Sleep()被调用,因此运行Task的线程将休眠。Cancel()被称为。IsCanceled。Task中的代码没有机会意识到令牌已被取消,因此它仍在运行,因此IsCanceled返回false。ThrowIfCancellationRequested()再次被调用,这一次它抛出,这实际上取消了Task。这就是为什么ISCanceled将false返回给您的原因。如果希望它返回true,可以在检查IsCanceled之前添加类似Thread.Sleep(150)的内容,或者更好的是,实际上等待Task完成。
发布于 2012-12-15 21:20:48
任务在您要求取消之前结束,请看下面的内容,这可能有助于更好地了解如何解决您的问题
通过从这里读取http://social.msdn.microsoft.com/Forums/da-DK/parallelextensions/thread/9f88132a-f8bd-4885-ab63-645d7b6c2127,似乎可以在任务“真正”启动之前,而是在任务排队之后,使用令牌来取消任务。
它更多地是取消计划中的任务,但尚未启动的一种方式。一旦任务运行,取消它的唯一方法是通过您自己在方法中的检查进行协作。否则,您必须始终启动任务,然后在内部检查它,这将增加许多额外的、不必要的开销。
发布于 2012-12-15 21:34:21
这不是回答,而是写在评论里的时间太长了
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可以很好地阅读。https://stackoverflow.com/questions/13896269
复制相似问题