2010-10-23 33 views
3

我在某些類上實現IObservable<T>接口。我使用Reflector來弄清楚這通常是在Rx中完成的。關於如何可觀察到的保持其用戶的軌跡,並通過他們的OnNext方法通知他們,我偶然發現了類似下面的代碼:我應該使用列表<IObserver>還是僅僅使用Action <T>來跟蹤IObservable的訂閱者?

private List<Observer<T>> observers; 

// subscribe a new observer: 
public IDisposable Subscribe(IObserver<T> observer) 
{ 
    observers.Add(observer); 
    ... 
} 

// trigger all observers' OnNext method: 
... 
foreach (IObserver<T> observer in observers) 
{ 
    observer.OnNext(value); 
} 

由於所有代表都是多投,不能這樣被簡化爲:

Action<T> observers; 

// subscribe observer: 
public IDisposable Subscribe(IObserver<T> observer) 
{ 
    observers += observer.OnNext; 
    ... 
} 

// trigger observers' OnNext: 
... 
observers(value); 

還是有特定的優勢,以第一種方法(性能,線程/併發問題,&hellip;)?

回答

5

一般來說,呼籲與會代表分別給你更多的控制權的行爲:

  • 如果一名代表提出,你可以保持通話的人,例如,或者從列表中移除故障委託一個例外。
  • 如果您想要並行調用代表,這非常簡單。
  • 如果您需要以特定順序調用它們,您可以輕鬆地保證正確的順序(我不確定多播委託調用的順序是否已定義)。
+0

此外,您還可以運行與重複的問題,如果你使用的多播委託程序蟑螂。如果添加了兩個具有完全相同的OnNext方法的觀察者,然後刪​​除了一個觀察者,則會刪除它們的回調。 – SoftMemes 2010-10-23 20:17:01

+0

釋放:不,這不是問題。只有給定委託的第一個實例被刪除。 – Gabe 2010-10-23 21:25:21

+0

你說得對。然而,會發生的是,「錯誤的」代表將被刪除,這將改變觀察者被通知的命令(可能相關也可能不相關)。 – SoftMemes 2010-10-23 21:59:58

4

通常不實現IObservable<T>自己,你使用的生成方法(如Observable.Create)一個方法返回一個IObservable<T>

但是,如果你要自己實現的接口,你應該換一個內部Subject<T>將處理所有的併發問題爲您提供:

public class CustomObservable<T> : IObservable<T> 
{ 
    private Subject<T> subject = new Subject<T>(); 

    public IDisposable Subscribe(IObserver<T> observer) 
    { 
     return subject.Subscribe(observer); 
    } 

    private void EmitValue(T value) 
    { 
     subject.OnNext(value); 
    } 
} 

注意:如果您決定堅持使用委託(無論何種原因),至少確保你在你的IDisposable返回值被退訂:

observers += observer.OnNext; 
return Disposable.Create(() => observers -= observer.OnNext); 
+0

感謝您的回答。但請注意,我的庫不是基於Rx的,我只依賴.NET 4.0 BCL中的兩個接口。我只檢查了Rx實現,看看它通常如何完成。 – stakx 2010-10-25 14:49:58

+2

是的,這是偉大的建議!考慮直接像實現IEnumerable一樣執行IObservable;通常你會嘗試使用一個已經建好的IObservable實現,如Subject 2010-10-26 00:33:19

相關問題