データ ソースを常に同時実行の安全な側に置きたい場合は、常に安全に使用できるポインターを少なくとも 1 つ用意する必要があります。したがって、Observer オブジェクトの有効期間は、データ ソースの有効期限より前に終了しない必要があります。
これは、オブザーバーを追加するだけで実行できますが、削除することはありません。各オブザーバーにコア実装自体を実行させるのではなく、このタスクを ObserverImpl オブジェクトに委譲させることができます。この impl オブジェクトへのアクセスをロックします。これは大したことではありません。オブザーバーが ObserverImpl オブジェクトを使用してビジーな場合に備えて、GUI アンサブスクライバーがしばらくの間ブロックされることを意味します。GUI の応答性が問題になる場合は、サブスクリプション解除ジョブがプッシュされた、ある種の同時ジョブ キュー メカニズムを使用できます。(Windows の PostMessage のように)
サブスクライブを解除するときは、コア実装をダミー実装に置き換えるだけです。繰り返しますが、この操作はロックを取得する必要があります。これは確かにデータ ソースの待機を発生させますが、これは単なる [ロック - ポインター スワップ - ロック解除] であるため、リアルタイム アプリケーションには十分高速であると言えます。
ダミーのみを含む Observer オブジェクトをスタックするのを避けたい場合は、何らかの簿記を行う必要がありますが、これはリストから必要な Observer オブジェクトへのポインターを保持するオブジェクトのような些細なことに要約される可能性があります。
最適化 : Observer 自体が実行されている限り、実装 (実際の実装 + ダミー) も維持する場合は、実際のロックなしでこれを実行し、InterlockedExchangePointer などを使用してポインターを交換できます。最悪のシナリオ: ポインターがスワップされている間に委任呼び出しが行われている --> 大したことはなく、すべてのオブジェクトが存続し、委任を続行できます。次の委譲呼び出しは、新しい実装オブジェクトに対して行われます。(もちろん、新しいスワップを除いて)