2010-10-23 97 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

相关问题