在此answer中,代码被设计为在async task
的执行之间有延迟。
当我实现这个时,我有一个方法可以取消停止循环的令牌。我也在等待任务,以便在我继续之前完成任务。如果我没有抓住OperationCanceledException
,我将永远等待,但有了它,它会很有效。
我也尝试用while(true)
替换while (!cts.IsCancellationRequested)
,但它并没有停止等待。
我误解了用法吗?
private int count = 0;
private CancellationTokenSource cts;
private Task task;
public void ContinuousWorkTask(int interval)
{
cts = new CancellationTokenSource();
// Run the import task as a async task
task = Task.Run(async () => // <- marked async
{
try {
while (true) {
DoWork();
await Task.Delay(interval, cts.Token); // <- await with cancellation
}
}
catch (OperationCanceledException) { }
}, cts.Token);
}
private void DoWork()
{
count++;
}
public void Shutdown()
{
cts.Cancel();
task.Wait(); //Without the try/catch we never stop waiting
}
更新#1:显示一个非常简单的DoWork()
来说明这不是任务&#34;挂起的原因&#34;没有try
/ catch
阻止。
更新#2:我喜欢等待这项任务,因为我经常要做一些清理工作,例如将结果写入磁盘,我想确定它已经完成了。我可以将此作为IDisposable
Dispose()
方法的一部分。
更新#3:已经指出task.Wait()将收到AggregateException
。我认为这增加了支持,任务应该在内部捕获OperationCancelledException
以进行干净关闭,如我在我的示例中所示。
如果我不应该看到一个答案,这个答案可以解释为什么我应该从Shutdown()
代码中捕获它。我认为这是代码味道,但我可能错过了一个设计点。