2012-02-13 8 views
1

すべての.netコントロールがメインスレッド上に作成されていることが必要です。少なくとも、通常はそのインターフェイスにコントロールを統合することが目的です。さらに、コントロールのプロパティを変更するには、独自の呼び出しメソッドを使用してコントロールのスレッドからメソッドを呼び出す必要があります。どのようにプログラムでコントロールの所有スレッドを見つけることができます

コントロールを見て所有スレッドを直接識別する方法はありますか?

逆に、現在のスレッドが「メインスレッド」であるかどうかを検出できますか? Visual Studioが実行時に見られるメインスレッドとして識別するスレッドに関して特別なことはありますか、それとも単にVSがデバッグを初期化するために実行する最初のスレッドですか?

答えて

5

逆に、現在のスレッドが「メインスレッド」であるかどうかを検出できますか?

Control.InvokeRequiredを使用して、適切なスレッドにいるかどうかを確認できます。そうでない場合は、Control.InvokeまたはControl.BeginInvokeを使用してコールを所有スレッドにマーシャリングする必要があります。

実行時に表示されるメインスレッドとしてVisual Studioが識別するスレッドには特別なものがありますか、それとも単にVSがデバッグを初期化するために実行する最初のスレッドですか?

それは実際にWindowsのメッセージポンプを処理しているSynchronizationContextを作成するために使用されているスレッドです。このスレッドは、常にSTAスレッド(Thread.ApartmentStateを参照)としてマークされ、適切な同期コンテキストとメッセージポンプを実行します。 Application.Runメソッドは、これを通常のWindowsフォームアプリケーションのメインスレッド内に設定します。

+0

+1あなたが本当に必要だったら 'Control.Invoke(<現在のスレッドに注意を払うDelegate/Lambda)'を実行することができます。 – Basic

+0

私はInvokeRequiredを使用しましたが、いくつかは指摘したように、これはコントロールのハンドルが作成されるまで機能しません。所有スレッドは、特にCreateHandle()を呼び出すスレッドとして定義されているようです。しかし、制御とスレッドの関係がどこで維持されているか、そしてこの関係がプログラム的に見えるかどうかについてはまだ疑問が残っています。 –

+1

@JCollins InvokeRequired以外に直接アクセスする方法はありません。内部的には、GetWindowThreadProcessId(http://msdn.microsoft.com/en-us/library/windows/desktop/ms633522(v=vs.85).aspx)を使用して内部HWNDを「所有」するスレッドを取得します(Control .Handle)を実行し、GetCurrentThreadId(http://msdn.microsoft.com/en-us/library/windows/desktop/ms683183(v=vs.85).aspx)を使用して、実行スレッドが同じスレッド。これらのメソッドのどちらもマネージコードで直接公開されることはありません。 –

関連する問題