简体   繁体   English

转换`IObservable<T> ` 到 `IEnumerable <Task<T> &gt;`?

[英]Convert `IObservable<T>` to `IEnumerable<Task<T>>`?

I have a couple of asynchronous APIs that use callbacks or events instead of async .我有几个异步 API,它们使用回调或事件而不是async I successfully used TaskCompletionSource to wrap them as described here .我成功地使用TaskCompletionSource来包装它们, 如下所述

Now, I would like to use an API that returns IObservable<T> and yields multiple objects.现在,我想使用一个返回IObservable<T>并产生多个对象的 API。 I read about Rx for .NET, which seems the way to go.我读过 Rx for .NET,这似乎是要走的路。 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).但是,我对包含另一个依赖项和另一个新范式犹豫不决,因为我已经在这个应用程序中使用了很多对我来说是新的东西(比如 XAML、MVVM、C# 的 async/await)。

Is there any way to wrap IObservable<T> analogously to how you wrap a single callback API?有什么方法可以像包装单个回调 API 一样包装IObservable<T>吗? I would like to call the API as such:我想这样调用 API:

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.如果 observable 发出多个值,您可以将它们转换为Task<T> ,然后将它们添加到任何IEnumerable结构中。

Check IObservable ToTask .检查IObservable ToTask As discussed here, the observable must complete before awaiting otherwise more values might come over.正如此处所讨论的,observable 必须在等待之前完成,否则可能会出现更多值。

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:如果您想使用 Rx,那么您可以使用您的返回列表:

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

You can subscribe the OnCompleted/OnError handler.您可以订阅 OnCompleted/OnError 处理程序。

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.所以你得到了一系列你的结果,你就完成了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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