我应该使用List <iobserver>还是仅使用Action <t>来跟踪IObservable的订户?</t> </iobserver>

时间:2010-10-23 08:15:51

标签: c# .net delegates system.reactive

我正在某些类上实现IObservable<T>接口。我使用Reflector来确定Rx中通常如何做到这一点。关于观察者如何跟踪其订阅者并通过他们的OnNext方法通知他们,我偶然发现了与此类似的代码:

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);

或者第一种方法(性能,线程/并发问题,......)是否具有特定优势?

2 个答案:

答案 0 :(得分:5)

通常,单独调用代理可以让您更好地控制行为:

  • 例如,如果一位代表提出异常,您可以继续呼叫其他代理,或从列表中删除有缺陷的代理。
  • 如果你想并行调用代表,那真的很容易。
  • 如果您需要按特定顺序调用它们,您可以轻松保证正确的顺序(我不确定是否定义了多播委托调用的顺序)。

答案 1 :(得分:4)

通常您不自己实现IObservable<T>,使用其中一种生成方法(如IObservable<T>)从方法返回Observable.Create

但是,如果您要自己实现接口,则应该包装一个内部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);
    }
}

NB:如果您决定坚持代表(无论出于何种原因),至少要确保取消订阅IDisposable返回值:

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