Должен ли я предпочесть бросить или вернуться при запросе отмены?

Рассмотрим два следующих подхода к обработке отмены через 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). С другой стороны, вызывающий абонент не обязательно может знать, какой подход мы выберем, поэтому он должен настроить try/catch для OperationCancelledException независимо от того, какой вариант мы выберем.

1 ответ

ThrowIfCancellationRequested был разработан для продолжения задач. Бросок останавливает всю цепочку продолжения (за исключением продолжений обработки отмены). Необработанный OperationCancelledException в задании отменит TaskТокен отмены также (если есть).

В вашем случае нет Task, Вы можете определить свой собственный интерфейс. Но имейте в виду, что тот, кто вызывает ваш метод, должен также иметь возможность увидеть, была ли ваша операция отменена или нет - в конце концов, что-то еще должно было вызвать отмену, если все, что у вас есть, - синхронные методы. В зависимости от того, что означает отмена, возвращая ошибку, пустой результат, ложь или выбрасывая исключение (но, вероятно, нет OperationCancelledException в любом случае!) каждый из них имеет смысл - вам нужно адаптировать его к тому типу интерфейса, который вы создаете.

Другие вопросы по тегам