Recently I encountered a situation where having an asynchronous operation represented both as a Task<T>
and as an IObservable<T>
would be advantageous. The task representation maintains the state of the operation (IsCompleted
, IsFaulted
etc), while the observable representation enables the composition of multiple operations in interesting ways (Concat
, Merge
, Switch
etc), handling automatically the cancellation of any operation that has been unsubscribed along the way, solving this way the problem of fire-and-forgotten asynchronous operations. So I've become interested about ways to combine these two representations.
The easy, and probably correct, way to combine them would be through composition: creating a type that stores internally a Task<T>
and an IObservable<T>
, and exposes them as two of its properties. But in this question I am interested about the challenging, and probably impractical, possibility of a type that is a Task<T>
and is an IObservable<T>
at the same time. A type that can be passed directly to APIs that accept either tasks or observables, and do the right thing in either case. So it can't be just a task-like object. It must inherit from the real thing, the Task<T>
class itself. Something like this:
public class AsyncOperation<TResult> : Task<TResult>, IObservable<TResult>
{
public AsyncOperation(Func<CancellationToken, Task<TResult>> action)
{
//...
}
}
Creating an AsyncOperation
instance should invoke immediately the supplied action. In other words an AsyncOperation
should represent a hot task/observable combo.
Is it possible to create such a type?
Btw here is a thread in the ReactiveX/RxJava library that proves that others have thought about this problem before: No "isCompleted" or "isErrored" methods on Observable