Existem interfaces IObservable e IObserver no .NET (também aqui e aqui ). Curiosamente, a implementação concreta do IObserver não mantém uma referência direta ao IObservable. Não sabe em quem está inscrito. Só pode invocar o cancelador de assinatura. "Por favor, puxe o alfinete para cancelar a inscrição."
edit: O cancelador de assinatura implementa o IDisposable
. Eu acho que esse esquema foi empregado para evitar o problema do ouvinte caducado .
Duas coisas ainda não estão totalmente claras para mim.
- A classe Unsubscriber interna fornece o comportamento de assinar e esquecer? Quem (e quando exatamente) chama
IDisposable.Dispose()
o Cancelador de assinatura? O coletor de lixo (GC) não é determinístico.
[Aviso: no geral, passei mais tempo com C e C ++ do que com C #.] O que deve acontecer se eu quiser inscrever um observador K em um L1 observável e o observador já estiver inscrito em algum outro L2 observável?
K.Subscribe(L1); K.Subscribe(L2); K.Unsubscribe(); L1.PublishObservation(1003); L2.PublishObservation(1004);
Quando executei esse código de teste no exemplo do MSDN, o observador permaneceu inscrito no L1. Isso seria peculiar no desenvolvimento real. Potencialmente, existem 3 caminhos para melhorar isso:
- Se o observador já tiver uma instância de cancelamento de inscrição (ou seja, já está inscrita), será silenciosamente cancelada a inscrição no provedor original antes de assinar uma nova. Essa abordagem oculta o fato de não ser mais assinada pelo provedor original, o que pode se tornar uma surpresa mais tarde.
- Se o observador já tiver uma instância de cancelamento de inscrição, será lançada uma exceção. Um código de chamada bem comportado deve cancelar a assinatura do observador explicitamente.
- O Observer assina vários fornecedores. Essa é a opção mais intrigante, mas isso pode ser implementado com IObservable e IObserver? Vamos ver. É possível para o observador manter uma lista de objetos de cancelamento de assinatura: um para cada fonte. Infelizmente,
IObserver.OnComplete()
não fornece uma referência ao provedor que a enviou. Portanto, a implementação do IObserver com vários provedores não seria capaz de determinar de qual deles cancelar a inscrição.
O IObserver do .NET pretendia se inscrever em vários IObservables?
A definição de livro didático do padrão de observador exige que um observador possa se inscrever em vários provedores? Ou é opcional e depende da implementação?