Должен ли я использовать список или просто действие , чтобы отслеживать подписчиков iBServable?

StackOverflow https://stackoverflow.com/questions/4003077

Вопрос

Я реализую IObservable<T> Интерфейс на некоторых классах. я использовал Отражатель Чтобы выяснить, как это обычно делается в 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);

Или есть ли у специальных преимуществ к первому подходу (производительность, проблемы с резьбой / параллелизмом, ...)?

Это было полезно?

Решение

В целом, позвонив делегатам индивидуально дает вам больше контроля над поведением:

  • Если один делегат поднимает исключение, вы можете продолжать звонить другим, например, или удалить неисправный делегат из вашего списка.
  • Если вы хотите позвонить делегатам параллельно, это действительно легко.
  • Если вам нужно позвонить им в определенном порядке, вы можете легко гарантировать правильный порядок (я не уверен, что порядок разговора многоадресной передачи определен).

Другие советы

Обычно вы не реализуете 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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top