メイン VCL スレッドを使用する
メイン VCL スレッドを使用するには、次の基本的な手順があります。
- アプリケーションでコンポーネントが受け取る Windows メッセージを処理する、別のルーチンを作成します。
- 定期的に CheckSynchronize を呼び出します。
- 必要な場合は、スレッドを排他的に使用するためのスレッドローカル変数を宣言します。
別のルーチンを作成するには:
- アプリケーション内のすべてのオブジェクトのために、各種のオブジェクト プロパティへのアクセスと、各種のオブジェクト メソッドの実行を行うメイン スレッド ルーチンを記述します。
- Delphi の場合は TThread.Synchronize メソッド、C++ の場合は TThread::Synchronize メソッドを使用して、このルーチンを呼び出します。 次のコード例では、Synchronize を使用してメソッドを呼び出しています。
procedure TMyThread.PushTheButton begin Button1.Click; end; procedure TMyThread.Execute; begin ... Synchronize(PushThebutton); ... end;
void TMyThread::PushTheButton() { Form1->Button1->Click(); } void __fastcall TMyThread::Execute() { ... Synchronize( (TThreadMethod)&PushTheButton ); ... }
Synchronize は、メイン スレッドがメッセージ ループに入るのを待ってから、渡されたメソッドを実行します。
メモ: Synchronize はメッセージ ループを使用するため、コンソール アプリケーションでは使用できません。 コンソール アプリケーションでは、クリティカル セクションのような他のメカニズムを使用して、VCL オブジェクトへのアクセスを保護します。
CheckSynchronize を呼び出すには:
- メイン スレッド内で定期的に CheckSynchronize を呼び出し、バックグラウンド スレッドがメイン スレッドと実行を同期できるようにします。
- 安全にバックグラウンド スレッドを呼び出せるようにするには、アプリケーションがアイドルのときに(たとえば、OnIdle イベント ハンドラから)CheckSynchronize を呼び出します。
スレッドローカル変数を使用するには:
- スレッド内で実行中のすべてのルーチンに対してグローバルにしたいが、同じスレッド クラスの他のインスタンスには共有されない、変数を特定します。
- Delphi では、次のように threadvar セクション内にこれらの変数を宣言します。
threadvar x: integer;
C++ では、次のように __thread 修飾子を使ってこれらの変数を宣言します。
int __thread x;
メモ: threadvar セクションは、グローバル変数のみに使用します。 ポインタ変数や関数変数(長い文字列などのコピーオンライト セマンティクスを用いる型)には、使用しないでください。
メモ: C++ で __thread 変数を初期化する場合は、定数式で初期化しなければなりません。 たとえば、int __thread foo = 3; は正式なステートメントですが、int __thread foo = get_value(); は実行時に初期化が発生するため許可されません。