我在CancellationToken
和CancellationTokenSource
周围创建了一个小包装器。我遇到的问题是CancelAsync
的{{1}}方法无法按预期工作。
我遇到了CancellationHelper
方法的问题。要取消正在运行的任务,它会调用ItShouldThrowAExceptionButStallsInstead
,但该任务实际上未被取消,并且不会在await coordinator.CancelAsync();
上抛出异常
task.Wait
似乎运行良好并使用ItWorksWellAndThrowsException
,这根本不是异步方法。
当我在异步方法中调用coordinator.Cancel
的Cancel方法时,为什么没有取消任务的问题?
不要让CancellationTokenSource
混淆你,只是为了不让任务提前完成。
让代码说明一切:
waitHandle
答案 0 :(得分:8)
.Net中的取消是合作的。
这意味着持有CancellationTokenSource
信号取消的那个和持有CancellationToken
的那个需要检查是否已发出取消信号(通过轮询CancellationToken
或通过注册代表来在发出信号时运行。)
在Task.Run
中,您使用CancellationToken
作为参数,但是您不会在任务内部检查它,因此只有在任务之前发出令牌信号才会取消任务必须有机会开始。
要在任务正常运行时取消,您需要检查CancellationToken
:
var task = Task.Run(() =>
{
token.ThrowIfCancellationRequested();
}, token);
在您的情况下,您屏蔽了ManualResetEvent
,因此您无法查看CancellationToken
。您可以将代理注册到释放重置事件的CancellationToken
:
token.Register(() => waitHandle.Set())