Below just a simple race between 2 button in 2 threads,
and this will freeze other components on the form.
procedure moveButton1();
var
I: Integer;
begin
for I := 0 to 6000 do
Form1.Button1.Left := Form1.Button1.Left - 1;
Form1.Caption := 'Button1 won!';
EndThread(0);
end;
procedure moveButton2();
var
I: Integer;
begin
for I := 0 to 6000 do
Form1.Button2.Left := Form1.Button2.Left - 1;
Form1.Caption := 'Button2 won!';
EndThread(0);
end;
procedure TForm1.Button3Click(Sender: TObject);
var
thread1, thread2,tick : Integer;
id1, id2 : LongWord;
begin
thread1 := BeginThread(nil,
0,
Addr(moveButton1),
nil,
0,
id1);
thread2 := BeginThread(nil,
0,
Addr(moveButton2),
nil,
0,
id2);
CloseHandle(thread1);
CloseHandle(thread2);
end;
The VCL (and parts of the RTL) is not thread-safe, so you cannot move components around from a thread. You have several options:
TTimercomponent. You don’t need a thread and the timer’s event handler will be executed in the context of the main thread. The timer was designed exactly for things like that.TThreadprovides a static methodSynchronizethat does exactly that.SendMessageorPostMessageand handle this message in the form.You might also consider to use the
TThreadwrapper class instead of usingBeginThreadandEndThreadexplicitly when working with threads.