Отмена. Часть 3: Обнаружение Отмены. Начало
Нередко возникает желание определить, действительно ли запрос на отмену что-то отменил. Отмена – это скоординированная операция, и иногда коду, запрашивающему отмену, необходимо знать, действительно ли отмена имела место или операция просто завершилась нормально.
В контракте отмены есть способ сообщить об этом: методы, принимающие CancellationToken, по соглашению должны выдавать исключение OperationCanceledException при их отмене. Это верно для всех методов BCL и должно быть так и в вашем коде.
Ответ на отмену
Самый распространённый сценарий обнаружения отмены — не обрабатывать исключение при отмене. Обычно исключение OperationCanceledException просто игнорируется:
async Task TryDoSomethingAsync()
{
using CancellationTokenSource cts = new();
// Создаём что-то, что может отменять cts
try
{
await DoAsync(cts.Token);
}
catch (Exception ex) when
(ex is not OperationCanceledException)
{
// Обработка исключения
}
}
Код выше обработает непредвиденные ошибки, но проигнорирует исключения отмены.
Если код должен сделать что-то другое при отмене, можно обработать это в блоке catch:
async Task DoSomethingAsync()
{
using CancellationTokenSource cts = new();
// Создаём что-то, что может отменять cts
try
{
await DoAsync(cts.Token);
}
catch (OperationCanceledException)
{
// Обработка отмены
}
catch (Exception ex)
{
// Обработка исключения
}
}
Однако подумайте, действительно ли вам нужно это делать, потому что это редкий случай, вызывает вопросы по логике кода, а также такой код сложно тестировать.
Окончание следует…
Источник: https://blog.stephencleary.com/2022/03/cancellation-3-detecting-cancellation.html