9

私はSynchronizationContextクラスについて学んでいます。SynchronizationContext.SetSynchronizationContext()WinForm/WPFアプリケーションのコンテキストで呼び出すための一般的な使用シナリオを理解しようとしています。SynchronizationContextスレッドのを設定するとはどういう意味ですか?いつ、なぜそれをすべきですか?また、設定した場合、いつか設定を解除する必要がありますか?

編集:

彼の答えの中で、@ Hans Passantは、なぜ私が考えているのかと尋ねましたSetSynchronizationContext()。私が持っているアイデアは、ワーカースレッドにコンテキストを設定して、そのスレッドで実行されているコードが使用するコンテキストを持つようにすることです。

private void button3_Click(object sender, EventArgs e)
{
    var syncContext = SynchronizationContext.Current;
    Task.Factory.StartNew(() =>
    {
        // Setup the SynchronizationContext on this thread so 
        // that SomeAsyncComponentThatNeedsACurrentContext
        // will have a context when it needs one
        if (SynchronizationContext.Current == null)
            SynchronizationContext.SetSynchronizationContext(syncContext);

        var c = new SomeAsyncComponentThatNeedsACurrentContext();
        c.DoSomething();

    });
}
4

2 に答える 2

16

一般に、これを正しく設定するには、特定の UI クラス ライブラリに任せる必要があります。Winforms は WindowsFormsSynchronizationContext インスタンスを自動的にインストールし、WPF は DispatcherSynchronizationContext をインストールし、ASP.NET は AspNetSynchronizationContext をインストールし、Store アプリは WinRTSynchronizationContext などをインストールします。UI スレッドがイベントをディスパッチする方法に合わせて調整された、非常に具体的な同期プロバイダー。

これらのアプリケーション環境がメイン スレッドを使用する方法には、何か特別なものがあります。それらはすべてディスパッチャ ループを実装し、スレッドセーフなキューを使用して通知を受け取ります。一般に、Windows GUI プログラミングでは「メッセージ ループ」として知られています。これは、コンシューマーを実装するディスパッチャー ループを使用した、プロデューサー/コンシューマーの問題に対する一般的な解決策です。

ワーカー スレッド用の独自の同期プロバイダーを作成するには、最初にそのようなスレッドがこの同じメカニズムを実装する必要があります。つまり、ConcurrentQueue のようなスレッドセーフなキューが必要になり、キューから通知を取得して実行するためにスレッドを作成する必要があります。デリゲート オブジェクトは適切な選択です。これで、Post メソッドの実装に問題はなくなります。SendOrPostCallback デリゲートをキューに追加するだけです。Send メソッドを実装するには追加の作業が必要です。スレッドは、デリゲートが取得されて実行されたことを通知する必要があります。そのため、キュー オブジェクトにも AutoResetEvent が必要です。

スレッドが一般的に有用なスレッドにならなくなったことに注意してください。これらの通知をディスパッチする必要があるため、行き詰まります。そして、既存の同期プロバイダーがすでにこれらすべてをどのように行っているか。したがって、アプリが Winforms アプリの場合は、非表示のダミー フォームを使用してワーカー スレッドで Application.Run() を呼び出すこともできます。また、自動的にその同期プロバイダーを無料で入手できます。

于 2011-01-11T14:51:33.327 に答える
2

MSDN マガジンの 2011 年 2 月号には、SynchronizationContexts と .NET ユニバース全体でのさまざまな実装に関する Google の記事が掲載されていました。

http://msdn.microsoft.com/en-us/magazine/gg598924.aspx

私にとっては、この問題に関する混乱の一部を解消するのに本当に役立ちました. 一般に、Hans が言うように、WinForms/WPF アプリケーションでは、使用する必要はなく、使用すべきではありません。SetSynchronizationContext()

于 2011-08-11T13:45:54.900 に答える