当我在异步方法中调用CancellationTokenSource的Cancel方法时,为什么不取消任务?

时间:2015-06-22 08:47:25

标签: c# asynchronous task cancellationtokensource cancellation-token

我在CancellationTokenCancellationTokenSource周围创建了一个小包装器。我遇到的问题是CancelAsync的{​​{1}}方法无法按预期工作。

我遇到了CancellationHelper方法的问题。要取消正在运行的任务,它会调用ItShouldThrowAExceptionButStallsInstead,但该任务实际上未被取消,并且不会在await coordinator.CancelAsync();上抛出异常

task.Wait似乎运行良好并使用ItWorksWellAndThrowsException,这根本不是异步方法。

当我在异步方法中调用coordinator.Cancel的Cancel方法时,为什么没有取消任务的问题?

不要让CancellationTokenSource混淆你,只是为了不让任务提前完成。

让代码说明一切:

waitHandle

1 个答案:

答案 0 :(得分:8)

.Net中的取消是合作的。

这意味着持有CancellationTokenSource信号取消的那个和持有CancellationToken的那个需要检查是否已发出取消信号(通过轮询CancellationToken或通过注册代表来在发出信号时运行。)

Task.Run中,您使用CancellationToken作为参数,但是您不会在任务内部检查它,因此只有在任务之前发出令牌信号才会取消任务必须有机会开始。

要在任务正常运行时取消,您需要检查CancellationToken

var task = Task.Run(() =>
{
    token.ThrowIfCancellationRequested();
}, token);

在您的情况下,您屏蔽了ManualResetEvent,因此您无法查看CancellationToken。您可以将代理注册到释放重置事件的CancellationToken

token.Register(() => waitHandle.Set())