Il existe des interfaces IObservable et IObserver dans .NET (également ici et ici ). Fait intéressant, l'implémentation concrète de l'IObserver ne contient pas de référence directe à l'IObservable. Il ne sait pas à qui il est abonné. Il ne peut invoquer que l'abonné. "Veuillez retirer l'épingle pour vous désinscrire."
edit: le désabonné implémente le IDisposable
. Je pense que ce schéma a été utilisé pour éviter le problème de l'auditeur périmé .
Cependant, deux choses ne sont pas tout à fait claires pour moi.
- La classe Unsubscriber interne fournit-elle le comportement d'abonnement et d'oubli? Qui (et quand exactement) fait appel
IDisposable.Dispose()
au désabonné? Le garbage collector (GC) n'est pas déterministe.
[Avertissement: dans l'ensemble, j'ai passé plus de temps avec C et C ++ qu'avec C #.] Que se passe-t-il si je veux abonner un observateur K à un L1 observable et que l'observateur est déjà abonné à un autre L2 observable?
K.Subscribe(L1); K.Subscribe(L2); K.Unsubscribe(); L1.PublishObservation(1003); L2.PublishObservation(1004);
Lorsque j'ai exécuté ce code de test contre l'exemple de MSDN, l'observateur est resté abonné à L1. Ce serait particulier dans le développement réel. Potentiellement, il existe 3 pistes pour améliorer cela:
- Si l'observateur a déjà une instance de désabonnement (c'est-à-dire qu'elle est déjà abonnée), il se désabonne discrètement du fournisseur d'origine avant de s'abonner à une nouvelle. Cette approche masque le fait qu'il n'est plus abonné au fournisseur d'origine, ce qui peut devenir une surprise plus tard.
- Si l'observateur possède déjà une instance de désabonnement, alors lève une exception. Un code d'appel qui se comporte bien doit désinscrire explicitement l'observateur.
- Observer est abonné à plusieurs fournisseurs. C'est l'option la plus intrigante, mais peut-elle être mise en œuvre avec IObservable et IObserver? Voyons voir. Il est possible pour l'observateur de conserver une liste des objets non abonnés: un pour chaque source. Malheureusement,
IObserver.OnComplete()
ne fournit pas de référence au fournisseur qui l'a envoyé. Ainsi, l'implémentation IObserver avec plusieurs fournisseurs ne serait pas en mesure de déterminer lequel désinscrire.
Le serveur IObserver de .NET était-il destiné à s'abonner à plusieurs serveurs IObservables?
La définition classique du modèle d'observateur exige-t-elle qu'un seul observateur doit être en mesure de s'abonner à plusieurs fournisseurs? Ou est-elle facultative et dépendante de la mise en œuvre?