У меня есть короткая асинхронная задача, которую часто нужно отменять после ее запуска. Класс «Task» имеет индикатор IsCanceled, который, я думаю, было бы удобно использовать, чтобы указать, что асинхронная задача была отменена без выполнения до завершения, но, насколько я могу судить, единственный способ пометить асинхронную задачу как отмененную чтобы вызвать исключение TaskCanceledException в асинхронной функции. Регулярное выбрасывание исключения, чтобы указать на ситуацию, которая возникает без исключения, противоречит тому, как я понимаю, что следует использовать исключения. Кто-нибудь знает лучший способ указать, что асинхронная задача должна быть отменена, когда ожидается, что она будет происходить часто?
Моя следующая лучшая альтернатива — вернуть структуру, имеющую собственное свойство IsCanceled:
(Для краткости я проигнорировал некоторые хорошие методы кодирования и стиля)
class MightBeCanceled<T>
{
public readonly T Value;
public readonly bool IsCanceled;
public MightBeCanceled(T value) { Value = value; IsCanceled = false; }
public static MightBeCanceled<T> Canceled = new MightBeCanceled<T>(default(T), true);
private MightBeCanceled(T value, bool isCanceled) { Value = value; IsCanceled = isCanceled; }
}
...
static async Task<MightBeCanceled<int>> Foo()
{
if (someCancellationCondition)
return MightBeCanceled<int>.Canceled;
else
return new MightBeCanceled<int>(42);
}
static async void Bar()
{
var mightBeCanceled = await Foo();
if (mightBeCanceled.IsCanceled)
; // Take canceled action
else
; // Take normal action
}
Но это кажется избыточным и более сложным в использовании. Не говоря уже о том, что это создает проблемы согласованности, потому что будет два IsCanceled (один в Task и один в MightBeCanceled).