Using the main VCL thread consists of the following basic steps:
- Create a separate routine to handle Windows messages received by components in your application.
- Call CheckSynchronize periodically.
- Declare thread-local variables, as necessary, for exclusive use by your thread.
To create a separate routine
- Write a main thread routine that handles accessing object properties and executing object methods for all objects in your application.
- Call the routine using the TThread.Synchronize (Delphi) or TThread::Synchronize method. The following code is an example of how to call a method using 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 waits for the main thread to enter the message loop and then executes the passed method.
Note: Because Synchronize uses a message loop, it does not work in console applications. For console applications, use other mechanisms, such as critical sections, to protect access to VCL objects.
To call CheckSynchronize
- Call CheckSynchronize periodically within the main thread to enable background threads to synchronize execution with the main thread.
- To ensure the safety of making background thread calls, call CheckSynchronize when the application is idle, for example, from an OnIdle event handler.
To use a thread-local variable
- Identify variables that you want to make global to all the routines running in your thread but not shared by other instances of the same thread class.
- For Delphi, declare these variables in a threadvar section, for example,
For C++, declare these variables with the __thread modifier:
Note: Use the threadvar
section for global variables only. Do not use it for Pointer and Function variables or types that use copy-on-write semantics, such as long strings.
Note: For C++, if you initialize a __thread
variable, you must initialize it to a constant expression. For example,
int __thread foo = 3; is a legal statement, but
int __thread foo = get_value(); is not permitted because the initialization occurs at runtime.