Должен ли я использовать список или просто действие , чтобы отслеживать подписчиков iBServable?
-
25-09-2019 - |
Вопрос
Я реализую 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);