一个简单的线程的迷惑,知道的DFW帮忙一下,thanks(0分)

  • 主题发起人 主题发起人 aikede
  • 开始时间 开始时间
A

aikede

Unregistered / Unconfirmed
GUEST, unregistred user!
下面的代码,我创建一个线程做运算,为什么,执行线程期间,还是无法相应VCL的主消息
?????迷惑

TMyThread = class(TThread)
private
protected
procedure Execute;override;
public
procedure TMyThread.Execute;
var
i:integer;
MyTemp:single;
begin
FreeOnTerminate:=true;
for i:=0 to 90000000do
begin
if Terminated then
Break;
MyTemp:=sqrt(sqrt(i));
end;
end;

procedure TForm1.Btn_TestClick(Sender: TObject);
var
TempThread:TMyThread;
begin
TempThread:=TMyThread.Create(false);
TempThread.Execute;
end;
 
不要直接调用线程对象的Execute方法——因为这样做只会在当前线程中执行。只要简单
的Resume一下,系统就会在新的线程中执行该线程的Execute方法了。
 
零分,郁闷。。。
回楼主。。。
对于线程的Create的构造函数,如果参数为False,则在构造后马上执行Execute方法了。
如果为True,则会在你Resume后才执行Execute方法,而不用你显示的去调用这个方法。
你所说的无法相应VCL主消息,Sorry,没看懂啥意思。
对于VCL的所参与的线程问题,由于是不安全的,所以简单来说一般都加上Synchronize来同步。
 
不好意思,本人实在没什么分,very very sorry
“你所说的无法相应VCL主消息”
对于这个,我的意思是执行改线程期间,比如我想拖动窗体 不相应
按我理解这是与主线程不同的一个线程,因此可以相应主线程的消息才对,
可以测试非我所想
 
to:creation-zy:
"不要直接调用线程对象的Execute方法——因为这样做只会在当前线程中执行。只要简单
的Resume一下"
什么意思?
是创建后先挂起,然后在resume吗?
 
明白了,
var
MyThread:TMyThread;
begin
MyThread:=TMyThread.Create(false);
MyThread.Resume;
end;
按楼上二位的说法改成这样,可以相应主消息了,
Thanks both of you very much,lngdtommy,creation-zy
 
修正一下:
MyThread:=TMyThread.Create(true);
MyThread.Resume;
或者
MyThread:=TMyThread.Create(false);
总算明白一点点
 
继续提问:
下面的VCL同步处理的线程
TMyVCLThread = class(TThread)
private
protected
procedure Execute;override;
procedure MyVCLAction;
public
end;

procedure TMyVCLThread.Execute;
var
i:integer;
MyTemp:single;
begin
FreeOnTerminate:=true;
Synchronize(MyVCLAction);
end;

procedure TMyVCLThread.MyVCLAction;
var
i:integer;
begin
for i:=0 to 1000000do
begin
if Terminated then
Break;
Form1.Btn_Caption.Caption:=IntTostr(i);
end;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
var
MyThread:TMyThread;
begin
MyThread:=TMyThread.Create(false);
end;
执行后提示:Canvasdo
not allow drawing?
难道,大家再指点一下,谢谢
 
是我弄错了,这样是可以的,可是我这样:加上showmessage也要用同步Synchronize吗?
procedure TMyThread.Execute;
var
i:integer;
MyTemp:single;
begin
FreeOnTerminate:=true;
for i:=0 to 9000000do
begin
if Terminated then
Break;
MyTemp:=sqrt(sqrt(i));
end;
if i=9000000 then
ShowMessage('ok');
end;
 
TMyVCLThread = class(TThread)
private
FValue:integer;
protected
procedure Execute;override;
procedure MyVCLAction;
public
end;

procedure TMyVCLThread.Execute;
var
i:integer;
MyTemp:single;
begin
FreeOnTerminate:=true;
for i:=0 to 1000000do
begin
FValue := i;
if Terminated then
Break;
Synchronize(MyVCLAction);
end;
end;

procedure TMyVCLThread.MyVCLAction;
begin
Form1.Btn_Caption.Caption:=IntTostr(FVAlue);
end;
 
yblee 正解
ShowMessage 不要加在线程中,否则会出错的
 
不是会出错。是可能会出错。线程中没有消息循环的代码,却显示用户界面。确实无法想象[:D]。楼主比较少上dfw。论坛可用积分较少。本次提问0分可以理解[8D]
 
在线程中涉及到主线程界面操作的,应该用Synchronize方法或者SendMessage消息将该操作放到主线程中执行.
 
后退
顶部