难道这个答案不应该有针对OperationCanceledException的try / catch吗?

时间:2016-11-09 03:07:05

标签: c# multithreading timer task-parallel-library .net-4.5

在此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()代码中捕获它。我认为这是代码味道,但我可能错过了一个设计点。

0 个答案:

没有答案