如何在一个线程结束后自动启动另一个线程????(100分)

  • 主题发起人 xiaoyaozh
  • 开始时间
X

xiaoyaozh

Unregistered / Unconfirmed
GUEST, unregistred user!
主线程中循环调用分线程1,如何在分线程1结束时自动回到主线程中再次调用分线程1?
 
可以在分线程的OnTerminate事件里写
线程执行完毕后会进入OnTerminate事件
在事件里再次创建分线程1就行了
 
那么我怎样让主线程等待分线程执行呢?
如果我在主线程里用WHILE TRUE DO 循环(主循环是不可以停的)
那么在begin
 和 END之间用什么指令让它等待分线程执行完再开始下一个循环?
 
tthread.waitfor
 
我是用消息来处理的,子线程在OnTerminate事件中发送给主线程一个自定义的消息,
主线程处理这个消息并起动相应的子线程。
 
你想编<中国黑客>吗?
 
可以用线程同步来处理
 
用WaitForSingleObject处理吧
 
to :教父
我试了一下,在ONTERMINATE事件写了一个语句,但是线程执行后该事件并没有被触发
哪位有源代码吗?
 
有没有设置
thread.onterminate := FOnterminate;
 
没有,在哪儿设呀?
另外下面的程序段:
procedure TForm1.Button1Click(Sender: TObject);
var
n:zThread1;
i:integer;
begin
// while truedo
for i:=0 to 10do
begin
n:= zthread1.create(false);
n.WaitFor;
sleep(1000);
// while not GoOndo
;
Memo1.lines.add('pass');
end;
end;
每次执行过n.WaitFor;以后就会出现一个错误提示
SYSTEM ERROR CODE 6
句柄无效
为什么呀
 
1、把zthread1的代码贴出来
2、在n:= zthread1.create(false)语句后面指定线程结束时释放资源的事件
即:n.onterminate := //自定义事件
 
unit zThread;
interface
uses
Dialogs, Classes;
type
zThread1 = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
procedure OnTerminate(Sender: TObject);
end;
implementation
uses sysutils,unit1;
{ Thread1 }
procedure zThread1.Execute;
var x:integer;
begin
FreeOnTerminate:=true;
x:=0;
unit1.Form1.Memo1.Lines.Add(inttostr(x))
end;

procedure zThread1.OnTerminate(Sender: TObject);
begin
showmessage('可以执行下一步');
end;

end.
 
你的程序在我这里运行没有出错啊!
真是奇怪?
你试一下在n.WaitFor前加上 if n<>nil then
关于你的线程的Onterminate事件用法不是那样用的
OnTerminate是从TThread继承过来的,在TThread的Execute事件
执行完毕且线程销毁之前TThread会进入该事件,你可以自己定义一个
TNotifyEvent事件并将Onterminate的指针执行该事件,这样线程执行完毕
就会进入你定义的事件
 
我修改后的程序:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons;
type
TForm1 = class(TForm)
BitBtn1: TBitBtn;
Memo1: TMemo;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure FOnTerminate(Sender: TObject);
end;

var
Form1: TForm1;
implementation
uses Unit2;
{$R *.DFM}
procedure TForm1.Bitbtn1Click(Sender: TObject);
var
n:zThread1;
i:integer;
begin
// while truedo
for i:=0 to 10do
begin
n:= zthread1.create(false);
n.OnTerminate:=FOnterminate;
if n<>nil then
n.WaitFor;
sleep(1000);
// while not GoOndo
;
Memo1.lines.add('pass');
end;
end;

procedure TForm1.FOnTerminate(Sender: TObject);
begin
showmessage('可以执行下一步');
end;
end.

unit Unit2;
interface
uses
Classes,unit1,windows,Sysutils,Dialogs;
type
zthread1 = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
end;

implementation
{ Important: Methods and properties of objects in VCL can only be used in a
method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure zthread1.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ zthread1 }
procedure zthread1.Execute;
var x:integer;
begin
FreeOnTerminate:=true;
x:=0;
Form1.Memo1.Lines.Add(inttostr(x)) { Place thread code here }
end;

end.
 
to siyan,
我在这里运行了一下你改过的程序,还是在同一个地方提示同一个错误
为什么呢,就为这一点错误我都搞了一天了,真想放弃!
:((
 
是不是还有其他代码?
如果没有我就不知道是什么原因了!
sigh,帮不上忙!
 
用WaitForSingleObject()等待子一个线程的结束,结束后做一些你要做的事情后
再次启动子线程,
 
你们不觉得用WaitFor之类的东西会浪费资源吗?用消息多好。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Unit2,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
protected
procedure USThread(var Msg: TMessage);
message US_THREAD;
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
uses Unit3;
{$R *.DFM}
{ TForm1 }
procedure TForm1.USThread(var Msg: TMessage);
var
Index: integer;
begin
Index:= Msg.WParam;
Memo1.Lines.Add(Format('第%d个线程结束', [Index]));
if Index < 10 then
begin
TTestThread.Create(Handle, Index+1, false);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
TTestThread.Create(Handle, 1, false);
end;

end.
/////////////////////////////////////////
unit Unit2;
interface
uses Messages;
const
US_THREAD = WM_USER + 1024;
implementation
end.
//////////////////////////////////////
unit Unit3;
interface
uses
Classes, Windows;
type
TTestThread = class(TThread)
private
{ Private declarations }
FOwnerHandle: integer;
FIndex: integer;
procedure FOnterminate(Sender: TObject);
protected
procedure Execute;
override;
public
constructor Create(OwnerHandle, Index: integer;
CreateSuspended: Boolean);
end;

implementation
uses
Unit2;
{ TTestThread }
constructor TTestThread.Create(OwnerHandle, Index: integer;
CreateSuspended: Boolean);
begin
FOwnerHandle := OwnerHandle;
FIndex:= Index;
OnTerminate := FOnterminate;
FreeOnTerminate := true;
inherited Create(CreateSuspended);
end;

procedure TTestThread.Execute;
var
i: integer;
begin
for i:=0 to 10000do
begin
end;
end;

procedure TTestThread.FOnterminate(Sender: TObject);
begin
SendMessage(FOwnerHandle, US_THREAD, FIndex, 0);
end;

end.

///////////////
D5+XP下测试通过
 
用PostMessage效果更好:)
 
顶部