给定一个Observable,它将在调用Subscribe后开始推送事件。如何将序列转换为IEnumerable。
2010年,Jon Skeet写下了他对RX的第一印象并写了这篇文章,这相当于我的需要。
public static List<T> ToList<T>(this IObservable<T> source)
{
List<T> ret = new List<T>();
source.Subscribe(x => ret.Add(x));
return ret;
}
https://codeblog.jonskeet.uk/2010/01/16/first-encounters-with-reactive-extensions/
虽然这个解决方案可行但似乎应该有更好的方法。
我们真正感兴趣的是能够await
以类似于Subscribe的方式使用observable。
await observable.ToList()
但是,这对我来说似乎不起作用。
我也研究过这两种方法
observable.ToEnumerable
observable.Next
更多信息
我打算用它来编写一些单元测试。
ReplaySubject
并使用测试替代品执行一系列操作。OnNext
答案 0 :(得分:3)
有趣的是,Skeet先生的实施非常糟糕。它不会阻塞,因此如果源恰好是重放主题(或类似主题),则只会将值泵入列表。因此对于大多数Observable Sequences,这只会返回一个空列表。 我确信乔恩知道这一点,但也许在翻译中迷失了。
ToList()
是你想要的,所以我想你也许没有完成?如果您只想要已知数量的元素,那么Take(x).ToList()
就足够了。
答案 1 :(得分:2)
修改强>:
如果您无法按照以下说明完成信息流,那么使用await
将无休止地等待。我会以其他方式测试。您可以查看Nuget Package Microsoft.Reactive.Testing
,它包含一些强大的测试工具。或者只是使用Subscribe
并在那里断言。
await
等待观察者完成或错误。您可能只需要向OnCompleted
添加ReactiveSubject
来电,您就可以了。以下代码适用于我:
var rs = new ReplaySubject<int>();
rs.OnNext(1);
rs.OnNext(2);
rs.OnNext(3);
rs.OnCompleted();
var l = await rs.ToList();
//l is equivalent to new List<int>() {1, 2, 3};