还是一个关于线程的问题,不明白
瞧代码:
unit unMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
unThread;
type
TfrmMain = class(TForm)
btn1: TButton;
btn2: TButton;
lbl1: TLabel;
lbl2: TLabel;
lbl3: TLabel;
procedure btn1Click(Sender: TObject);
procedure btn2Click(Sender: TObject);
private
{ Private declarations }
myThread:TMyThread;
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
EndThread:Boolean;
implementation
{$R *.dfm}
procedure TfrmMain.btn1Click(Sender: TObject);
begin
EndThread:=False;
myThread:=TMyThread.Create(False);
end;
procedure TfrmMain.btn2Click(Sender: TObject);
var
rv:DWORD;
wv:Integer;
i:Integer;
begin
rv:=5;
myThread.Terminate;
Application.ProcessMessages; //就是这里了,一定要加这句,下面的一句WaitForSingleObject()才有效,才不会超时! 如果不加,都是超时的(当然是线程还没有执行完,要Terminate中断的情况下)
rv:=WaitForSingleObject(myThread.Handle,5000);
case rv of
WAIT_ABANDONED: lbl3.Caption:='中断了';
WAIT_OBJECT_0: lbl3.Caption:='正常结束';
WAIT_TIMEOUT : lbl3.Caption:='超时';
5:lbl3.Caption:='55555';
end;
end;
end.
unit unThread;
interface
uses
Windows, Classes;
type
TMyThread = class(TThread)
private
{ Private declarations }
procedure OnMyThreadTerminate(Sender:TObject);
protected
procedure Execute; override;
end;
implementation
uses unMain;
{ TMyThread }
procedure TMyThread.Execute;
var
i,j:Integer;
k:Double;
begin
OnTerminate:=OnMyThreadTerminate;
//FreeOnTerminate:=True; //这个设置了,就不能用WaitForSingleObject()函数了,因为句柄被释放了,我估计
for i:=0 to 2000000 do
begin
if Terminated then
Break;
for j:=0 to 2000 do
begin
if Terminated then
Break;
k:=(i+1) / Sqrt(Sqr((j+5)/5)+16);
end;
end;
end;
procedure TMyThread.OnMyThreadTerminate(Sender: TObject);
begin
frmMain.lbl1.Caption:='Thread Terminate';
end;
end.
如果不加Application.ProcessMessages;这句代码,也可以在别的地方设置myThread.Terminate;比如在另一个按钮点击事件里也行。
有人能解释下这个事吗?
有时想结束一个线程,设置了Terminate=true,不一定马上结束,所以想用WaitForSingleObject()来判断,线程运行时是无信号状态,结束了是有信号状态。
也看了看<<windows核心编程>>相关章节,都是用API实现的。