I have a short async task that will frequently need to be canceled after it has started. The "Task" class has an IsCanceled indicator which I think would be convenient to use to indicate that the async task was canceled without running to completion, but as far as I can tell the only way to have an async Task be marked as canceled is to throw a TaskCanceledException in the async function. Throwing an exception routinely, to indicate a situation which occurs unexceptionally, goes against how I understand exceptions should be used. Does anyone know a better way to indicate an async task to be canceled when it is expected to happen frequently?
My next-best alternative is to return a structure that has it's own IsCanceled property:
(I've ignored some good coding and style practices for brevity here)
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
}
But this seems redundant and harder to use. Not to mention it introduces consistency problems because there will be two IsCanceled's (one in the Task and one in the MightBeCanceled).