【问题标题】:Dispose of Observable Items as they are generated在 Observable Item 生成时处理它们
【发布时间】:2020-12-05 18:17:46
【问题描述】:

我有一个IObservable,它会生成一次性物品,并且在其生命周期内可能会生成无限数量的物品。因此,我想在每次生成新项目时处理最后一个项目,因此 Using 运算符不适用于此。有没有不同的 Rx.NET 算子可以完成这个功能?

【问题讨论】:

    标签: c# reactive-programming system.reactive


    【解决方案1】:

    如果您有IObservable<IDisposable> source,那么执行此操作以自动处理先前的值并在序列结束时进行清理:

    IObservable<IDisposable> query =
        Observable.Create<IDisposable>(o =>
        {
            var serial = new SerialDisposable();
            return new CompositeDisposable(
                source.Do(x => serial.Disposable = x).Subscribe(o),
                serial);
        })
    

    【讨论】:

    • 如果源是 Subject,它似乎也可以正常工作。我可以使用 Subject 还是必须先转换为 observable ?我有它作为 subject.Do(x => serial.Disposable = x).Subscribe(o),
    • @XavierJohn - Subject 是 Observable 和 Observer。他们就是这样。所以不需要转换。
    【解决方案2】:

    这是一个 DisposePrevious 运算符,基于 Enigmativity 的 solution 的略微修改版本。

    /// <summary>Disposes the previous element of an observable sequence. The last
    /// element is disposed when the observable sequence completes.</summary>
    public static IObservable<T> DisposePrevious<T>(this IObservable<T> source)
        where T : IDisposable
    {
        return Observable.Using(() => new SerialDisposable(), serial =>
            source.Do(x => serial.Disposable = x));
    }
    

    SerialDisposable 类...

    表示一个一次性资源,其底层一次性资源可以被另一个一次性资源替换,从而导致前一个底层一次性资源的自动处置。

    【讨论】:

      【解决方案3】:

      我遇到了 Shlomo 的 this answer 并将其改编为我自己的目的:

      public class DisposerProperty<T> : IDisposable, IObservable<T> where T : IDisposable
      {
          private IDisposable Subscription { get; }
          private IObservable<T> Source { get; }
      
          public T Value { get; private set; }
      
          public DisposerProperty(IObservable<T> source, T defaultValue = default)
          {
              Value = defaultValue;
              Source = source;
              Subscription = source.Subscribe(t =>
                                              {
                                                  Value?.Dispose();
                                                  Value = t;
                                              });
          }
      
          public void Dispose() => Subscription.Dispose();
      
          /// <inheritdoc />
          public IDisposable Subscribe(IObserver<T> observer) => Source.Subscribe(observer);
      }
      

      现在,每当我想要这个功能时,我只需使用 DisposerProperty&lt;T&gt; 而不是直接订阅 observable。

      【讨论】:

      • 这是个坏主意,有办法使用现有的运算符和类型来做到这一点。
      • @Enigmativity 为什么这样不好?比如,这会以什么方式适得其反?
      • 实现自己的可观察类很难做到正确。除非您经过严格的测试,否则我不会使用它。
      猜你喜欢
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 2020-02-05
      • 2020-04-25
      • 2011-04-10
      • 1970-01-01
      • 2010-10-06
      相关资源
      最近更新 更多