We currently have many uses of AsyncLazy but they are not participating in cooperative cancellation because passing a CancellationToken at "await time" is not possible.
Would it be possible to provide an extension to pass in a CancellationToken before awaiting the AsyncLazy? Perhaps a Task<T> WithCancellationAsync(CancellationToken) method, so the caller can provide a token, like this:
var value = await myAsyncLazy.WithCancellationAsync(cancellationToken);
And then have an overload on the constructor to allow providing a Func<T, CancellationToken, Task> that can propagate this token to the underlying factory.
I'm aware I could "bake in" a cancellation token via a closure when specifying the factory, but that is not only convoluted, it is also common that the place that defines the factory doesn't have access to the CancellationToken object yet, so it can't always be used. It also doesn't work for anything that is cross-request, for example an AsyncLazy inside of a singleton registration in a WebAPI: in that case, I want the first request to the object to define provide CancellationToken, so it cannot be provided via a closure at all.
I also could couple the AsyncLazy await with a separate timeout task, but then even when the timeout is reached, the actual factory will keep executing behind the scenes and will not be cancelled. This gets me some benefits (the caller can be cancelled) but it is not perfect either.
We currently have many uses of
AsyncLazybut they are not participating in cooperative cancellation because passing aCancellationTokenat "await time" is not possible.Would it be possible to provide an extension to pass in a
CancellationTokenbefore awaiting theAsyncLazy? Perhaps aTask<T> WithCancellationAsync(CancellationToken)method, so the caller can provide a token, like this:And then have an overload on the constructor to allow providing a
Func<T, CancellationToken, Task>that can propagate this token to the underlying factory.I'm aware I could "bake in" a cancellation token via a closure when specifying the factory, but that is not only convoluted, it is also common that the place that defines the factory doesn't have access to the
CancellationTokenobject yet, so it can't always be used. It also doesn't work for anything that is cross-request, for example anAsyncLazyinside of a singleton registration in a WebAPI: in that case, I want the first request to the object to define provideCancellationToken, so it cannot be provided via a closure at all.I also could couple the
AsyncLazyawaitwith a separate timeout task, but then even when the timeout is reached, the actual factory will keep executing behind the scenes and will not be cancelled. This gets me some benefits (the caller can be cancelled) but it is not perfect either.