ライブラリが単一の同期コンテキストからのみ使用されることがわかっている場合、静的メンバーを使用して同期コンテキストをキャプチャできない理由はわかりません (オプション A)。
この依存関係を「明示的」にする必要があるのはなぜですか?
オプション A が問題になる可能性があるのは、ライブラリが複数の同期コンテキストから同時に使用される可能性がある場合です。(たとえば、独自のスレッドとメッセージ ポンプで実行される複数の UI ウィンドウ)。ただし、これはかなり珍しいことです。ほとんどの場合、単一の UI スレッドと単一の同期コンテキストがあります。
また、アプリケーションが (同期コンテキストを介して) UI スレッドへのシリアル化を強制せずにいくつかのイベントを処理したい場合、それはできません。
これらの問題がライブラリの問題でない場合は、オプション A が有効です。
編集 - コメントへの応答:
ジョエル、あなたが説明したことを考えるとこれが役立つかどうかはわかりませんが、明示的な同期コンテキストを使用したい場合に考慮すべきことの 1 つは、作成する必要なくパラメーターを格納するためにスレッドローカル ストレージを使用することです。パラメータを取るメソッドのオーバーライド。
たとえば、私は過去に、API の呼び出し元が現在の呼び出しスレッドの既定の同期コンテキストを使用できるようにするだけでなく、別の同期コンテキストを明示的に設定できるようにする必要がありました。私が取ることができた 1 つのアプローチは、同期コンテキスト パラメーターを渡すことができる API メソッドのオーバーロードを提供することでした。私の場合、これは非常に醜いものでした。かなりまれなユース ケースに対して多数のメソッド オーバーロードを作成する必要があったからです。
そのため、代わりに、現在の同期コンテキストがオーバーライドされる「スコープ」の作成を処理するクラスを作成しました (それにより、呼び出されたメソッドに効果的に渡します)。このクラスは、(順番に) 1) 現在の同期コンテキストのキャッシュ、2) 呼び出し元によって指定された同期コンテキストへの現在のコンテキストの設定、および 3) 'スコープ' の最後での同期コンテキストのリセットを処理します。
外観は次のとおりです。
public class SyncContextScope : IDisposable
{
SynchronizationContext m_contextOnEntry;
/// <summary>
/// Constructor
/// </summary>
/// <param name="useContext"></param>
public SyncContextScope(SynchronizationContext useContext)
{
m_contextOnEntry = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(useContext);
}
#region IDisposable Members
void IDisposable.Dispose()
{
SynchronizationContext.SetSynchronizationContext(m_contextOnEntry);
}
#endregion
}
そして、あなたはそれを次のように使います:
using(new SyncContextScope(yourSyncContext))
{
yourApi.CallSomeMethod();
}
API のメソッド (上記の例の CallSomeMethod) は、SynchronizationContext.Current (TLS を使用して同期コンテキストを保存する) を利用できるようになりました。synchronizationcontext パラメータを提供する必要はありません。