2010-11-13 69 views
5

通常,當您訂閱某個值的更改時,您也有興趣知道初始值。我希望我的IObservable緩存最新(或初始)值並在訂閱時推送該值。如何獲得IObservable以在訂閱時推送最新值

當使用普通的事件,我經常和代碼,看起來像

x.SomeEvent += SomeEventHandler; 
SomeEventHandler(x, EventArgs.Empty); 

使用的IObservable我希望的東西,推動初值包裹事件結束。如果我有多個用戶,他們應該創造的IObservable之後但如果該事件觸發訂閱之前獲得在訂閱 我有一些代碼,工程的最新值的權利,如果我訂閱:

class Program 
{ 
    static void Main() 
    { 
     var s = new Source { Value = 1 }; 
     var values = Observable.Return(s.Value).Concat(
      Observable.FromEvent(
       h => s.ValueChanged += h, 
       h => s.ValueChanged -= h) 
      .Select(_ => s.Value)); 
     using (values.Subscribe(Console.WriteLine)) 
     { 
      s.Value = 2; // prints 1,2 as expected 
     } 
     using (values.Subscribe(Console.WriteLine)) 
     { 
      s.Value = 3; // prints 1,3 - expected 2,3 
     } 
    } 
} 

class Source 
{ 
    private int _value; 
    public int Value 
    { 
     get { return _value; } 
     set 
     { 
      if (_value == value) 
       return; 
      _value = value; 
      if (ValueChanged != null) 
       ValueChanged(this, EventArgs.Empty); 
     } 
    } 

    public event EventHandler ValueChanged; 
} 

如何創建一個IObservable按預期工作?

+0

'。選擇(_ => s.Value)' - 這是非常奇怪的,可能會打破東西。你不能改變'ValueChanged'事件,所以事件參數包含新值嗎? – dtb 2010-11-13 15:29:13

+0

我沒有寫我正在聽的代碼。如果我是我只是暴露一個IObservable而不是:) – 2010-11-13 16:17:04

回答

6

解決方案是訂閱BehaviorSubject給觀察者,並訂閱所有觀察者到BehaviorSubjectBehaviorSubject會記住最後的通知,並在訂閱時通知新的觀察者。

看看Observable.Publish擴展方法,它具有initialValue參數。這會創建一個IConnectableObservable,它在內部使用BehaviorSubject

var s = new Source { Value = 1 }; 

var values = Observable.FromEvent(h => s.ValueChanged += h, 
            h => s.ValueChanged -= h) 
         .Select(e => e.NewValue) 
         .Publish(s.Value); 

using (values.Connect())       // subscribes subject to event 
{ 
    using (values.Subscribe(Console.WriteLine)) // subscribes to subject 
    { 
     s.Value = 2; 
    }           // unsubscribes from subject 

    using (values.Subscribe(Console.WriteLine)) // subscribes to subject 
    { 
     s.Value = 3; 
    }           // unsubscribes from subject 

}           // unsubscribes subject from event 

(未經測試)

相關問題