多线程程序在处理中,经常会出现某个线程死掉的情况,也不释放,而且当有一个线程死掉以后,其他线程也会马上紧跟着死掉。我如何能够在主程序中释放调死掉的线程呢。
代码如下 //主程序创建调用线程语句
//stringgrid1中每一行相当于一个任务,每个线程执行一个任务。
for j := 1 to stringgrid1.RowCount - 1 do
begin
if stringgrid1.Cells[5,j] = '未处理' then
begin
if (ThreadCount < maxthread) then
begin
application.ProcessMessages;
threadcount := threadcount + 1;
with ttaskthread.Create(j,idftp1) do
begin
onterminate := doonterminal20;
end;
end
else
stringgrid1.Cells[6,j] := '等待空闲进程';
end;
end;
procedure TForm1.doonterminal20(Sender: TObject);
begin
ThreadCount := ThreadCount - 1;
end;
//线程声明
type
TTaskThread = class(TThread)
private
msg,errormsg,errorid,errorinfo : string;
xh :Integer; //记录主窗体stringgrid 的行号
IdFtp1 :TidFtp;
procedure changegrid2; //更改主窗体stringgrid1文件处理状态栏
protected
procedure Execute; override;
Public
constructor Create(postid:integer;ftp:tidftp);
destructor destroy;override;
end;
// 线程创建
constructor TTaskThread.Create(postid:integer;ftp:tidftp);
begin
IdFtp1 := Tidftp.Create(Application);
IdFtp1.Host := ftp.Host;
IdFtp1.Port := ftp.Port;
IdFtp1.Username := ftp.Username;
IdFtp1.Password := ftp.Password; xh := postid; // 为该线程执行stringgrid中任务的行号 FreeOnTerminate := true;
inherited Create(false);//创建线程后直接运行
end;
//线程释放
destructor TTaskThread.destroy;
begin
try
try
IdFtp1.free;
idftp1 := nil;
except
errormsg := '出错';
synchronize(changegrid2);
raise;
end;
Finally
inherited Destroy;
end;
end;//线程执行代码
procedure TTaskThread.Execute;
var
...
begin
while not Terminated do
begin
// ...
//准备下载数据文件
Try
IdFTP1.Get(sourcefilename, desttempfilename, TRue,FALSE);
except
Terminate;
break;
end;
//...
end;
end;程序可以正常运行,只是有的时候会出现某个线程死在IdFTP1.Get(...)的地方,即使我的IdFTP1.Get(...)是在try中的,程序仍然不能继续执行下去。然后马上所有其他的线程也会死在这个地方。我怀疑是IDFTP和ftpserver的问题,我用的是windows IIS ftpserver。但我没办法解决。所以只好请问有没有办法能在主程序中判断某个线程死掉了,并杀掉这个线程,释放资源。在线等待:解决立即给分。
代码如下 //主程序创建调用线程语句
//stringgrid1中每一行相当于一个任务,每个线程执行一个任务。
for j := 1 to stringgrid1.RowCount - 1 do
begin
if stringgrid1.Cells[5,j] = '未处理' then
begin
if (ThreadCount < maxthread) then
begin
application.ProcessMessages;
threadcount := threadcount + 1;
with ttaskthread.Create(j,idftp1) do
begin
onterminate := doonterminal20;
end;
end
else
stringgrid1.Cells[6,j] := '等待空闲进程';
end;
end;
procedure TForm1.doonterminal20(Sender: TObject);
begin
ThreadCount := ThreadCount - 1;
end;
//线程声明
type
TTaskThread = class(TThread)
private
msg,errormsg,errorid,errorinfo : string;
xh :Integer; //记录主窗体stringgrid 的行号
IdFtp1 :TidFtp;
procedure changegrid2; //更改主窗体stringgrid1文件处理状态栏
protected
procedure Execute; override;
Public
constructor Create(postid:integer;ftp:tidftp);
destructor destroy;override;
end;
// 线程创建
constructor TTaskThread.Create(postid:integer;ftp:tidftp);
begin
IdFtp1 := Tidftp.Create(Application);
IdFtp1.Host := ftp.Host;
IdFtp1.Port := ftp.Port;
IdFtp1.Username := ftp.Username;
IdFtp1.Password := ftp.Password; xh := postid; // 为该线程执行stringgrid中任务的行号 FreeOnTerminate := true;
inherited Create(false);//创建线程后直接运行
end;
//线程释放
destructor TTaskThread.destroy;
begin
try
try
IdFtp1.free;
idftp1 := nil;
except
errormsg := '出错';
synchronize(changegrid2);
raise;
end;
Finally
inherited Destroy;
end;
end;//线程执行代码
procedure TTaskThread.Execute;
var
...
begin
while not Terminated do
begin
// ...
//准备下载数据文件
Try
IdFTP1.Get(sourcefilename, desttempfilename, TRue,FALSE);
except
Terminate;
break;
end;
//...
end;
end;程序可以正常运行,只是有的时候会出现某个线程死在IdFTP1.Get(...)的地方,即使我的IdFTP1.Get(...)是在try中的,程序仍然不能继续执行下去。然后马上所有其他的线程也会死在这个地方。我怀疑是IDFTP和ftpserver的问题,我用的是windows IIS ftpserver。但我没办法解决。所以只好请问有没有办法能在主程序中判断某个线程死掉了,并杀掉这个线程,释放资源。在线等待:解决立即给分。
因为IdFTP1.Get是一个过程,没有返回值
只能从OnStatus、OnWork等事件里取的信息
以上仅做参考。
Windows NT提供了一个函数GetThreadTimes(),它可以提供详细的时间信息。
其声明如下:
function GetThreadTimes(hThread: THandle; var lpCreationTime,lpExitTime,
lpKernelTime,lpUserTime: TFileTime):BOOL; stdcall;
hThread参数是线程的句柄,其他参数都是变参,由GetThreadTimes()函数返回它们的值。其中:
•lpCreationTime线程创建的时间。
•lpExitTime线程退出的时间。如果线程还在执行,此值无意义。
•lpKernelTime执行操作系统代码所用的时间。
•lpUserTime执行应用程序本身代码所用的时间。
以上四个参数都是TFileTime类型。
注意请记住函数GetThreadTimes()只适用于WindowsNT/2000。如果你在Windows95/98下调用,它总是返回False。非常不幸,Windows95/98没有提供获取线程时间的手段。