все строки ниже (reader.Close () и т. Д.) Будут выполнены, и будет вызвано исключение при выполнении ThrowIfCancelationRequested () - это правильно? Я что-то упустил?
Если так, есть ли способ отменить все сразу?
Прежде всего, операция, которую вы хотите отменить, имеет значение явно поддержка отменяется. Итак, вы должны приложить все усилия, чтобы использовать код для выполнения некоторой операции таким образом, который каким-то образом принимает CancellationToken
в качестве аргумента. Если это невозможно, у вас нет другого шанса.
Вот почему эта концепция называется Совместное аннулирование . Потому что почти всегда обе стороны должны знать, что отмена произошла. Клиентская сторона должна знать, что код был фактически отменен, клиенту недостаточно знать, что аннулирование было запрошено. Для вызываемой стороны важно знать о том, что отмена была запрошена, чтобы правильно завершить себя.
Относительно проверки отмены операции при выполнении Close
метода stream
и reader
. Вы должны вызывать методы очистки всегда, независимо от того, отменена операция или нет, если вы хотите избежать утечек памяти. Конечно, я предлагаю вам использовать оператор using
, который автоматически выполнит эту очистку.
И, между прочим, для того, чтобы сделать какую-либо функцию отменяемой, вам не нужно проверять, запрашивается ли отмена перед выполнением каждой строки. Вам просто нужно проверить, отменен ли запрос до и после выполнения какой-либо длительной операции. И передайте токен отмены, если эти длительные операции поддерживают отмену с помощью свойства токена отмены.
Кроме того, вам нужно посмотреть побочных эффектов . Не отменяйте, если вы уже столкнулись с побочными эффектами, которые ваш метод не готов отменить, если вы окажетесь в несогласованном состоянии.
Некоторые общие кодовые блоки могут быть такими:
if(ct.IsCancellationRequested)
{
break; // or throw
}
await DoSomething(ct);
if (ct.IsCancellationRequested)
{
// if there is no side-effect
return; // or throw
// or, we already did something in `DoSomething` method
// do some rollback
}
В качестве решения вы можете использовать несколько различных объектов, таких как HttpClient
или WebRequest
для выполнения асинхронного, ожидаемого и отменяемого веба. запрос. Вы можете посмотреть эту ссылку для подробностей реализации.