Dois-je utiliser la liste ou simplement Action pour garder la trace des abonnés d'un IObservable?

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

Question

J'implémentant l'interface IObservable<T> sur certaines classes. Je réflecteur pour comprendre comment cela se fait généralement dans Rx . En ce qui concerne la façon dont une observable garde la trace de ses abonnés et les notifie par leur méthode de OnNext, je suis tombé sur un code similaire à ceci:

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

Étant donné que tous les délégués sont multi-acteurs, ne pourrait-il être simplifié à:

Action<T> observers;

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

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

Ou y at-il des avantages spécifiques à la première approche (performance, questions threading / ..., accès concurrentiel)?

Était-ce utile?

La solution

En général, appelant les délégués individuellement, vous donne plus de contrôle sur le comportement:

  • Si un délégué soulève une exception, vous pouvez continuer à appeler les autres, par exemple, ou supprimer le délégué faillée de votre liste.
  • Si vous voulez appeler les délégués en parallèle, il est vraiment facile.
  • Si vous avez besoin de les appeler dans un certain ordre, vous pouvez facilement garantir le bon ordre (je ne suis pas sûr que l'ordre de délégué multicast appels est défini).

Autres conseils

En général, vous ne vous mettez pas en œuvre IObservable<T>, vous retournez un IObservable<T> à partir d'une méthode utilisant l'une des méthodes de génération (comme Observable.Create).

Cependant, si vous allez implémenter l'interface vous-même, vous devez envelopper un Subject<T> interne qui traitera toutes les questions de concurrence pour vous:

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: Si vous décidez de rester avec le délégué (quelle qu'en soit la raison), au moins assurez-vous dans votre IDisposable le désabonnement valeur de retour:

observers += observer.OnNext;
return Disposable.Create(() => observers -= observer.OnNext);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top