C# 如果不迭代所有内容,如何处理可观察状态
如果我在IObservable上使用ToEnumerable扩展,则用户可能不会迭代所有元素。在这种情况下,如何正确处理Observable.Create中声明的IDisposable 为了便于讨论,我们假设直接将IObservable返回给用户不是一个选项,在这种情况下,用户可以自己实现取消C# 如果不迭代所有内容,如何处理可观察状态,c#,system.reactive,rx.net,C#,System.reactive,Rx.net,如果我在IObservable上使用ToEnumerable扩展,则用户可能不会迭代所有元素。在这种情况下,如何正确处理Observable.Create中声明的IDisposable 为了便于讨论,我们假设直接将IObservable返回给用户不是一个选项,在这种情况下,用户可以自己实现取消 private IObservable<Object> MakeObservable() { return Observable.Create(async (observer, ca
private IObservable<Object> MakeObservable()
{
return Observable.Create(async (observer, cancelToken) =>
{
using(SomeDisposable somedisposable = new SomeDisposable())
{
while(true)
{
Object result = somedisposable.GetNextObject();
if(result == null)
{
break;
}
observer.OnNext(result);
}
}
}
}
public IEnumerable<Object> GetObjects()
{
return MakeObservable().ToEnumerable();
}
public void Test()
{
IEnumerable<Object> e = GetObjects();
int i = 0;
foreach(Object o in e)
{
if(i++ == 10)
break;
}
//somedisposable is not disposed here!!!
}
问题是您的Create定义没有返回,因此无法停止。如果你改变你的源观测到的东西基于定时器,然后它的工作良好。请尝试以下代码:
public IEnumerable<long> GetObjects()
{
return Observable
.Interval(TimeSpan.FromSeconds(1.0))
.Finally(() => Console.WriteLine("Done."))
.ToEnumerable();
}
public void Test()
{
foreach (long i in GetObjects())
{
Console.WriteLine(i);
if (i == 10)
{
break;
}
}
}
运行时,您将获得以下输出:
0
1
2
3
4
5
6
7
8
9
10
Done.
这显然是在源观测上调用OnCompleted。谢谢。虽然我不会使用Interval,但这个答案帮助我理解了它发生的原因。我意识到我可以更多地使用cancelToken,它在退出foreach时似乎也会被取消。