2011-01-11 11 views
7

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

編集:私はSetSynchronizationContext()を考えた理由を彼の答えで

、@Hansアンパッサンは尋ねました。私が持っているアイデアは、ワーカースレッド上でコンテキストを設定して、そのスレッド上で実行されているコードが使用するコンテキストを持つようにすることです。

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(); 

    }); 
} 

答えて

12

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

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

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

あなたのスレッドが一般的に有用なスレッドになるのをやめたら、これらの通知をディスパッチする必要があります。既存の同期プロバイダがすでにこれをどのようにしているのか。したがって、アプリケーションがWinformsアプリケーションの場合、ダミーの目に見えない形式のワーカースレッドでApplication.Run()を呼び出すこともできます。そしてあなたは自動的にその同期プロバイダを無料で入手します。

+0

私の質問への更新をご覧ください。 – Sylvain

+0

私の更新プログラムはあなたの答えを変えますか?そのようなワーカースレッド上のSynchronizationContextの設定も避けなければならないと思いますか? – Sylvain

+0

私は本当にあなたがこれについて考えていることを聞きたいと思います...ありがとう – Sylvain

1

2011年2月号のMSDN Magazineには、Googleの記事ディスカッション「SynchronizationContexts」と.NETユニバースでのさまざまな実装がありました。

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

は私にとって、それは本当に問題をめぐる混乱のいくつかを明確に助けました。一般的に、Hansは、WinForms/WPFアプリケーションでは、使用する必要はなく、使用するべきではありません。SetSynchronizationContext()

関連する問題