下面是两个线程中两个按钮之间的简单竞争,
这将冻结表单上的其他组件。
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;发布于 2010-03-24 22:12:52
VCL (和RTL的一部分)不是线程安全的,因此您不能从线程中移动组件。您有几个选项:
TTimer组件。您不需要线程,定时器的事件处理程序将在主线程的上下文中执行。计时器是专门为线程中所有与VCL相关的东西设计的,比如that.TThread提供了一个执行此操作的静态方法Synchronize。SendMessage或PostMessage将消息从线程发送到窗体,并在窗体中处理此消息。在处理线程时,您还可以考虑使用TThread包装类,而不是显式地使用BeginThread和EndThread。
发布于 2010-03-25 03:09:46
使用Synchronize()将是同步移动按钮的过程的一种非常糟糕的方法。Synchronize()强制方法在主VCL线程中运行。它们会互相阻挡,所以一次只能移动一个按钮。这将避免在VCL中遇到非线程安全代码。
我不能重现表单冻结的问题,所以我不确定这是你的问题。你可能想看看别的地方。
https://stackoverflow.com/questions/2508216
复制相似问题