多线程程序在处理中,经常会出现某个线程死掉的情况,也不释放,而且当有一个线程死掉以后,其他线程也会马上紧跟着死掉。我如何能够在主程序中释放调死掉的线程呢。
代码如下    //主程序创建调用线程语句
//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。但我没办法解决。所以只好请问有没有办法能在主程序中判断某个线程死掉了,并杀掉这个线程,释放资源。在线等待:解决立即给分。

解决方案 »

  1.   

    严重关注!我也遇到类似问题困扰
    因为IdFTP1.Get是一个过程,没有返回值
    只能从OnStatus、OnWork等事件里取的信息
      

  2.   

    有可能是在Get事件中无响应,导致系统长时间等反应,而你的多线程又是要VCL同步的,所以有可能在它等待的时候导致其它的线程无法使用VCL(被锁住了),从而表现为死了
    以上仅做参考。
      

  3.   

    用这个函数试试,也许有用
    Windows NT提供了一个函数GetThreadTimes(),它可以提供详细的时间信息。
    其声明如下:
    function GetThreadTimes(hThread: THandle; var lpCreationTime,lpExitTime,
      lpKernelTime,lpUserTime: TFileTime):BOOL; stdcall;
    hThread参数是线程的句柄,其他参数都是变参,由GetThreadTimes()函数返回它们的值。其中:
    &#8226;lpCreationTime线程创建的时间。
    &#8226;lpExitTime线程退出的时间。如果线程还在执行,此值无意义。
    &#8226;lpKernelTime执行操作系统代码所用的时间。
    &#8226;lpUserTime执行应用程序本身代码所用的时间。
    以上四个参数都是TFileTime类型。
    注意请记住函数GetThreadTimes()只适用于WindowsNT/2000。如果你在Windows95/98下调用,它总是返回False。非常不幸,Windows95/98没有提供获取线程时间的手段。
      

  4.   

    我所说的死掉了是指线程死掉了,而主程序并没有死掉,主程序还可以响应鼠标。但我的程序是需要等所有stringgrid中的任务全部做完,才继续下面的处理,否则一直会对stringgrid循环操作。所以有一个线程死掉了,我的程序没法继续往下处理其他的事情了。
      

  5.   

    那如果get长时间没有反应,我如何知道,并且线程能够返回错误,而不是在那里象死了一样!!