Hay interfaces IObservable e IObserver en .NET (también aquí y aquí ). Curiosamente, la implementación concreta del IObserver no tiene una referencia directa al IObservable. No sabe a quién está suscrito. Solo puede invocar al suscriptor. "Por favor, tire del pin para darse de baja".
editar: El suscriptor implementa el IDisposable
. Creo que este esquema se empleó para evitar el problema del oyente caducado .
Sin embargo, hay dos cosas que no me quedan del todo claras.
- ¿La clase interna Unsubscriber proporciona el comportamiento de suscribirse y olvidar? ¿Quién (y cuándo exactamente) llama
IDisposable.Dispose()
a Unsubscriber? El recolector de basura (GC) no es determinista.
[Descargo de responsabilidad: en general, he pasado más tiempo con C y C ++ que con C #.] ¿Qué debería suceder si quiero suscribir un observador K a un L1 observable y el observador ya está suscrito a algún otro L2 observable?
K.Subscribe(L1); K.Subscribe(L2); K.Unsubscribe(); L1.PublishObservation(1003); L2.PublishObservation(1004);
Cuando ejecuté este código de prueba contra el ejemplo de MSDN, el observador permaneció suscrito a L1. Esto sería peculiar en el desarrollo real. Potencialmente, hay 3 vías para mejorar esto:
- Si el observador ya tiene una instancia de cancelación de suscripción (es decir, ya está suscrita), se da de baja silenciosamente del proveedor original antes de suscribirse a una nueva. Este enfoque oculta el hecho de que ya no está suscrito al proveedor original, lo que puede convertirse en una sorpresa más adelante.
- Si el observador ya tiene una instancia para cancelar la suscripción, se produce una excepción. Un código de llamada con buen comportamiento tiene que cancelar la suscripción del observador explícitamente.
- El observador se suscribe a múltiples proveedores. Esta es la opción más intrigante, pero ¿se puede implementar con IObservable e IObserver? Veamos. Es posible que el observador mantenga una lista de objetos para cancelar la suscripción: uno para cada fuente. Lamentablemente,
IObserver.OnComplete()
no proporciona una referencia al proveedor que lo envió. Por lo tanto, la implementación de IObserver con múltiples proveedores no podría determinar de cuál darse de baja.
¿IObserver de .NET estaba destinado a suscribirse a múltiples IObservables?
¿La definición de libro de texto del patrón de observador requiere que un observador pueda suscribirse a múltiples proveedores? ¿O es opcional y depende de la implementación?