[英]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.