多线程里的 Synchronize 请教!

jiangjunad 2011-11-03 05:18:41
因为一个工程项目,所以我像请教下多线程的 一个技巧!

procedure MyThread.SynchroEvent1;
var
WaitReturn : DWord ;
I:Integer;
begin
For I:=0 to 99999999 do Form1.Label3.Caption :=Inttostr(I);
end;

constructor MyThread.Create(lbl:TLabel;sleepSec:Integer); //参数传递
begin
FLabel:=lbl;
FSleepDec:=sleepSec;
FreeOnTerminate:=True; //让线程终止是触发OnTerminate事件
inherited Create(True);//不立即执行,只有调用resume才开始
end;


procedure MyThread.Execute;
var
i:Integer;
begin
for i:=0 to 1000 do begin
if Terminated then Break;
FLabel.Caption:=IntToStr(i);
Sleep(FSleepDec);
SynchroEvent1;
end;
end;

如果在Synchronize里使用了循环的话就会使程序卡死,工程里必须同步并且有循环!我像请教大家如何解决?
...全文
277 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ADSLAN 2011-11-20
  • 打赏
  • 举报
回复
你重载create时不是传递了一个 Label lbl给 FLabel
你同步的Label3 跟lbl不是一个???
把label3传递给LBL
然后线程类函数使用FLabel来显示相关数据就可以了
PengDeGang 2011-11-20
  • 打赏
  • 举报
回复
第一,不要直接在线程里操作VCL。
第二,把要同步的部分这么使用Synchronize(SynchroEvent1)
第三,SynchroEvent1应该简单,只包括循环内的部分就可以了。在Execute里加上For I:=0 to 99999999 do Synchronize(SynchroEvent1);
第四,循环很快的,不要每次都显示,SynchroEvent1里面if(i mod 13243=0) then Form1.Label3.Caption :=Inttostr(I);就可以了。
xiaowei_001 2011-11-19
  • 打赏
  • 举报
回复
1楼说的很好!
meegowei1 2011-11-04
  • 打赏
  • 举报
回复
要改成这样

var
count : integer ;
procedure MyThread.SynchroEvent1;
var
WaitReturn : DWord ;
I:Integer;
begin
FLabel.Caption:=IntToStr(count );
//移动这里是因为 vcl 调用不能在线程中进行,只能在主线程进行; 当然,在主线程进行时,会占用 cpu 时间,所以会产生你说的 卡住的问题
For I:=0 to 99999999 do Form1.Label3.Caption :=Inttostr(I);
end;

constructor MyThread.Create(lbl:TLabel;sleepSec:Integer); //参数传递
begin
FLabel:=lbl;
FSleepDec:=sleepSec;
FreeOnTerminate:=True; //让线程终止是触发OnTerminate事件
inherited Create(True);//不立即执行,只有调用resume才开始
end;


procedure MyThread.Execute;
begin
for count:=0 to 1000 do
begin
if Terminated then Break;

Sleep(FSleepDec);
SynchroEvent1;
end;
end;
shijies 2011-11-03
  • 打赏
  • 举报
回复
FLabel.Caption:=IntToStr(i); //不要直接在线程里操作VCL。
lhy 2011-11-03
  • 打赏
  • 举报
回复
把i设成MyThread的成员变量。
lhy 2011-11-03
  • 打赏
  • 举报
回复
第一,不要直接在线程里操作VCL。
第二,把要同步的部分这么使用Synchronize(SynchroEvent1)
第三,SynchroEvent1应该简单,只包括循环内的部分就可以了。在Execute里加上For I:=0 to 99999999 do Synchronize(SynchroEvent1);
第四,循环很快的,不要每次都显示,SynchroEvent1里面if(i mod 13243=0) then Form1.Label3.Caption :=Inttostr(I);就可以了。

1,184

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧