请求取消时,我应该更喜欢扔还是返回?

时间:2018-10-24 14:44:49

标签: c# async-await cancellation cancellation-token

考虑以下两种通过CancellationToken处理取消的方法:

public async Task DoAllAvailableWork(CancellationToken cancelToken)
{
    foreach (var job in GetAllAvailableWork())
    {
        await job.Process();

        if (cancelToken.IsCancellationRequested())
            return;
    }
}

public async Task DoAllAvailableWork(CancellationToken cancelToken)
{
    foreach (var job in GetAllAvailableWork())
    {
        await job.Process();

        cancelToken.ThrowIfCancellationRequested();
    }
}

在这种情况下,job.Process()正在进行一些原子工作,一旦开始就不应或无法停止,因此它不接受CancellationToken

有没有理由更喜欢其中一种方法?如果是,应该采用哪种方法?

检查IsCancellationRequested()对我来说比较干净,因为抛出意味着发生了一些错误,取消是我们明确计划要处理的情况(这就是为什么我们接受CancellationToken的原因) 。另一方面,调用者不一定知道我们将采用哪种方法,因此无论我们选择哪种选项,他们都必须为OperationCancelledException设置try / catch。

1 个答案:

答案 0 :(得分:1)

ThrowIfCancellationRequested设计用于任务继续。抛出停止整个延续链(取消处理延续除外)。任务中未处理的OperationCancelledException也将取消Task的取消令牌(如果有)。

在您的情况下,没有Task。您可以自由定义自己的界面。但是请记住,调用您方法的任何人还应该有一种方法来查看您的操作是否被取消-毕竟,如果您拥有的所有方法都是同步方法,则一定是其他原因导致了取消。根据取消的含义,返回错误,空结果,错误或引发异常(但无论如何OperationCancelledException都可能没有道理)-您需要根据自己的界面类型对其进行调整重新制作。