简体   繁体   中英

Convert `IObservable<T>` to `IEnumerable<Task<T>>`?

I have a couple of asynchronous APIs that use callbacks or events instead of async . I successfully used TaskCompletionSource to wrap them as described here .

Now, I would like to use an API that returns IObservable<T> and yields multiple objects. I read about Rx for .NET, which seems the way to go. However, I'm hesitant to include another dependency and another new paradigm, since I'm already using a lot of things that are new for me in this app (like XAML, MVVM, C#'s async/await).

Is there any way to wrap IObservable<T> analogously to how you wrap a single callback API? I would like to call the API as such:

foreach (var t in GetMultipleInstancesAsync()) {
    var res = await t;
    Console.WriteLine("Received item:", res);
}

If the observable emits multiple values, you can convert them to Task<T> and then add them to any IEnumerable structure.

Check IObservable ToTask . As discussed here, the observable must complete before awaiting otherwise more values might come over.

This guide here might do the trick for you too

public static Task<IList<T>> BufferAllAsync<T>(this IObservable<T> observable)
{
    List<T> result = new List<T>();
    object gate = new object();
    TaskCompletionSource<IList<T>> finalTask = new TaskCompletionSource<IList<T>>();

    observable.Subscribe(
        value =>
        {
            lock (gate)
            {
                result.Add(value);
            }
        },
        exception => finalTask.TrySetException(exception),
        () => finalTask.SetResult(result.AsReadOnly())
    );

    return finalTask.Task;
}

If you would like to use Rx then you can use your returning list:

GetMultipleInstancesAsync().ToObservable().Subscribe(...);

You can subscribe the OnCompleted/OnError handler.

Also you can wrap it a task list:

var result = await Task.WhenAll(GetMultipleInstancesAsync().ToArray());

So you got an array of your results and you are done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM