2009-06-24 12 views
6

WinFormsには、Control.BeginInvoke()があります。つまり、バックグラウンドスレッドからの呼び出しを、コントロールのハンドルを作成したメインUIスレッドにマーシャリングすることができます。手動でスレッドにマーシャリングする

これは問題ありませんが、これは2つの「標準」スレッドの間でどのように(C#で)行いますか?

メッセージを消費するプロセッサスレッドを持つサービスバスを作成しました。タイマーのスレッドで実行されているコードではなく、プロセッサスレッドが何かを実行させるタイマーが必要です。

もちろん、私はスレッドの同期化(Monitor/using() {...})を使うことができますが、どのように正常に行われたのか疑問に思っています。

答えて

11

残念ながら答えは難しいですが、スレッドの性質に大きく依存しているためです。

スレッド間のマーシャリングは魔法ではありません。それを可能にする基本的なメカニズムがあります。たとえばWinFormsでは、Control.Invokeスタイル関数はメッセージの受け渡しを介して機能します。 UIスレッドにメッセージがポストされていると、メッセージポンプは最終的にこのメッセージをポンピングし、それをマーシャル呼び出しに変換します。

標準スレッド間で呼び出しをマーシャリングするには、マーシャル呼び出しを検出できる何らかの機能が必要であり、その呼び出しが行われる必要があります。これは、通常、ある種のメッセージの受け渡しによって行われます。

IMHOこれを行う最も標準的な方法は、スレッドにSynchronizationContextの実装、提供、インストールをさせることです。これは、スレッド間のマーシャリングメカニズムを定義する標準的な方法です。

+1

私が探していた答えはSynchronizationContextでした - ありがとう! –

1

Windowsフォームではmessage loopが実行されます。そのため、すべての種類のタスクのUIスレッドにマーシャリングすることができます。スレッドの境界を越えて送信できるメッセージを繰り返し待ちます。

手動で行う場合は、独自のメッセージループ(1つ以上のスレッド用)を作成するか、ずっと簡単に同期プリミティブを使用します。 AutoResetEventは、このような状況のために適切なものと思われるでしょう。右の点でSetWaitOneのメソッドを呼び出すだけでいいです(実際はデッドロックにも注意してください)。

関連する問題