简体   繁体   English

Reactive Extensions ToEnumerable如果不迭代所有内容,如何处置可观察的状态

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM