[英]Reactive Extensions ToEnumerable how to dispose observable state if not iterating everything
If I use the ToEnumerable
extension on an IObservable
, there is a chance the user will not iterate all of the elements. 如果我在
IObservable
上使用ToEnumerable
扩展,则用户有可能不会迭代所有元素。 In that case how can the IDisposable
declared in Observable.Create
be properly disposed? 在这种情况下,如何正确处理
Observable.Create
声明的IDisposable
?
For the sake of argument let's say that it is not an option to directly return the IObservable
to the user (in which case the user could implement cancellation themselves). 出于争论的考虑,我们不能选择直接将
IObservable
返回给用户(在这种情况下,用户可以自己实现取消)。
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!!!
}
The issue is that your definition of Create
doesn't return so it can't be stopped. 问题在于您对
Create
的定义不会返回,因此无法停止。 If you change your source observable to something based on a timer then it works fine. 如果您将可观察的源更改为基于计时器的内容,则可以正常工作。 Try this code:
试试这个代码:
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;
}
}
}
When you run that you get this output: 运行时,将得到以下输出:
0 1 2 3 4 5 6 7 8 9 10 Done.
It's clearly calling OnCompleted
on the source observable. 显然,在可观察到的源上调用
OnCompleted
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.