.NETにはIObservableおよびIObserverインターフェイスがあります(こことここも)。興味深いことに、IObserverの具体的な実装は、IObservableへの直接参照を保持していません。誰が購読しているかはわかりません。購読解除者のみを呼び出すことができます。「登録を解除するにはピンを抜いてください。」
編集:購読解除者はを実装しIDisposable
ます。この方式は、リスナーの失効問題を防ぐために使用されたと思います。
しかし、2つのことは完全に明確ではありません。
- 内部のUnsubscriberクラスはsubscribe-and-forget動作を提供しますか?誰が(正確にはいつ)登録
IDisposable.Dispose()
解除者を呼び出すのですか?ガベージコレクター(GC)は確定的ではありません。
[免責事項:全体として、私はC#よりもCおよびC ++に多くの時間を費やしました。] オブザーバーKをオブザーバブルL1にサブスクライブし、オブザーバーが他のオブザーバブルL2にすでにサブスクライブしている場合はどうなりますか?
K.Subscribe(L1); K.Subscribe(L2); K.Unsubscribe(); L1.PublishObservation(1003); L2.PublishObservation(1004);
このテストコードをMSDNの例に対して実行したとき、オブザーバーはL1にサブスクライブしたままでした。これは実際の開発に特有のものです。潜在的に、これを改善する3つの方法があります。
- オブザーバーがすでにサブスクライブ解除インスタンスを持っている(つまり、すでにサブスクライブしている)場合、オブザーバーは新しいプロバイダーにサブスクライブする前に、元のプロバイダーから静かにサブスクライブ解除します。このアプローチにより、元のプロバイダーにサブスクライブされなくなったという事実が隠されます。これは、後で驚くかもしれません。
- オブザーバーがすでにサブスクライブ解除インスタンスを持っている場合は、例外がスローされます。正常に動作する呼び出しコードは、オブザーバーを明示的にサブスクライブ解除する必要があります。
- オブザーバーは複数のプロバイダーにサブスクライブします。これは最も興味深いオプションですが、IObservableとIObserverで実装できますか?どれどれ。オブザーバがサブスクライバオブジェクトのリストを保持することは可能です:ソースごとに1つ。残念ながら、
IObserver.OnComplete()
それを送信したプロバイダーに戻って参照を提供していません。したがって、複数のプロバイダーを使用するIObserver実装は、どのプロバイダーからサブスクライブを解除するかを決定できません。
.NETのIObserverは、複数のIObservableをサブスクライブすることを目的としていましたか?
テキスト形式のオブザーバーパターンの定義では、1人のオブザーバーが複数のプロバイダーにサブスクライブできる必要があるか?それともオプションで実装に依存していますか?