C# 转换为'IObservable<;T>;`到`IEnumerable<;任务<;T>>;`?

C# 转换为'IObservable<;T>;`到`IEnumerable<;任务<;T>>;`?,c#,async-await,system.reactive,C#,Async Await,System.reactive,我有两个异步API,它们使用回调或事件而不是async。我成功地使用了TaskCompletionSource来包装它们 现在,我想使用一个返回IObservable并生成多个对象的API。我读到了关于Rx for.NET的文章,这似乎是一个不错的选择。然而,我不太愿意加入另一个依赖项和另一个新的范例,因为我已经在这个应用程序中使用了很多对我来说是新的东西(比如XAML、MVVM、C#的异步/等待) 有没有类似于包装单个回调API的方式包装IObservable?我想这样调用API: forea

我有两个异步API,它们使用回调或事件而不是
async
。我成功地使用了
TaskCompletionSource
来包装它们

现在,我想使用一个返回
IObservable
并生成多个对象的API。我读到了关于Rx for.NET的文章,这似乎是一个不错的选择。然而,我不太愿意加入另一个依赖项和另一个新的范例,因为我已经在这个应用程序中使用了很多对我来说是新的东西(比如XAML、MVVM、C#的异步/等待)

有没有类似于包装单个回调API的方式包装
IObservable
?我想这样调用API:

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

如果可观察对象发出多个值,您可以将它们转换为
任务
,然后将它们添加到任何
IEnumerable
结构中

检查。正如这里所讨论的,在等待之前必须完成可观测,否则可能会出现更多的值

公共静态任务BufferAllAsync(此IObservable可观察)
{
列表结果=新列表();
对象门=新对象();
TaskCompletionSource finalTask=新建TaskCompletionSource();
可观察。订阅(
值=>
{
锁(门)
{
结果:增加(价值);
}
},
exception=>finalTask.TrySetException(异常),
()=>finalTask.SetResult(result.AsReadOnly())
);
返回finalTask.Task;
}

如果您想使用Rx,则可以使用您的返回列表:

GetMultipleInstancesAsync().ToObservable().Subscribe(...);
您可以订阅OnCompleted/OnError处理程序

您还可以将其包装为任务列表:

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

所以你得到了一个结果数组,你就完成了。

如果你使用的是C#8,你可以使用另一个新的东西,叫做,否则你可以使用@Fabjan是的,看起来精神上是
iasyncenenumerable
IEnumerable
。它让您摆脱了临时的
await t t
,转而使用
await foreach(…)
。我只需要找出如何转换
IObservable
。也许某个地方有一个扩展方法。@jdm您可以在包中找到
ToAsyncEnumerable
扩展方法。我完全搞不清楚您在这里尝试的方向。你能提供一份报告吗?请包括您的API调用以及如何包装它们,以及您想要实现的方法的外壳。谢谢,但我实际上在寻找相反的方法。我已经有了
IObservable
,并且想要
ToObservable()的反面。另外,我不想等待每一个
任务完成(
whalll
),我想在它们出现时处理它们。然后简单地订阅您的可观察到的。GetMultipleInstancesAsync().Subscribe(…);此方法相当于库中方法
ToList
和方法
ToTask
的组合。
ToList
IObservable
转换为
IObservable
,然后
ToTask
将其转换为
任务。
var result = await Task.WhenAll(GetMultipleInstancesAsync().ToArray());