考虑以下两种通过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。

最佳答案

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

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

10-06 04:08
查看更多