重新初始化对象擦除事件时可观察到的FromEventPattern

时间:2018-11-12 21:07:35

标签: system.reactive

我正在尝试在一个类中设置一个可观察对象,该类在每次事件触发成员时都会滴答作响。

public class FooService
{

  private BarProvider _barProvider;
  public IObservable<BarChangedEventArgs> BarChanged { get; }

  public FooService()
  {        
    BarChanged = 
      Observable
        .FromEventPattern<BarChangedHandler, BarChangedEventArgs>(
          h => _barProvider.Changed += h,
          h => _barProvider.Changed -= h)
        .Select(p => p.EventArgs);
  }

  public void OccursSomeTimeAfterFooServiceCreation
  (
    Func<BarProvider> barProviderFactory
  )
  {
    _barProvider = barProviderFactory();
  }
}

我想我需要做的是在OccursLater方法中分配_barProvider的新值之后,设置可观察的事件处理程序,因为这是一个新的事件源。但是,我相信,在消费者可能已经订阅之后,在稍后设置BarChanged会破坏那些现有的订阅。

我希望FooService的使用者能够随时订阅BarChanged,并且将可观察项视为事件args流,而不管订阅创建后调用OccursSomeTimeAfterFooServiceCreation的次数如何。

2 个答案:

答案 0 :(得分:0)

问题是您没有观察类或变量。您观察到实例。

如果我理解正确,则您希望订阅者忽略观察到的实例发生更改的事实。

尝试这样的事情:

public class FooService
{
  private BarProvider _barProvider;
  private Subject<BarChangedEventArgs> subject = new Subject<BarChangedEventArgs>();
  public IObservable<BarChangedEventArgs> BarChanged { get; } = subject.AsObservable();

  public FooService()
  {        
  }

  public void OccursSomeTimeAfterFooServiceCreation
  (
    Func<BarProvider> barProviderFactory
  )
  {
    _barProvider = barProviderFactory();

    BarChanged = 
      Observable
        .FromEventPattern<BarChangedHandler, BarChangedEventArgs>(
          h => _barProvider.Changed += h,
          h => _barProvider.Changed -= h)
        .Select(p => p.EventArgs)
        .Subscribe(subject);
  }
}

答案 1 :(得分:0)

如果您的Observable-创作取决于可以更改的内容,例如您的barProvider,您应该始终从其他Observable检索那些,然后利用Switch()运算符。

为此,我使用了BehaviorSubject。

    public class FooService
    {
        public BehaviorSubject<BarProvider> _barProviderSubject = new BehaviorSubject<BarProvider>(null); //or initialize this subject with the barprovider of your choice

        public IObservable<BarChangedEventArgs> BarChanged { get; }

        public FooService()
        {
            var barChangedChanged = _barProviderSubject.Where(bP => bP != null).Select(bP =>
                Observable.FromEventPattern<BarChangedHandler, BarChangedEventArgs>(
                        h => bP.Changed += h,
                        h => bP.Changed -= h)
                    .Select(p => p.EventArgs)
            );
            BarChanged = barChangedChanged.Switch();
        }

        public void OccursSomeTimeAfterFooServiceCreation
        (
            Func<BarProvider> barProviderFactory
        )
        {
            _barProviderSubject.OnNext(barProviderFactory());
        }
    }