我需要获得子线程的返回值,我知道等待进程结束用    WaitForSingleObject(ExcelThread.Handle,INFINITE);获得返回值用 GetExitCodeThread?  这个怎么用啊, 我的子线程返回的是一个TStringList类型的值,这个问题困惑我很久了,恳请高手露个头.

解决方案 »

  1.   

    var   
          ExitCode:   Integer;               
      begin   
          GetExitCodeThread(ThreadHandle,   ExitCode);   
        
          ShowMessage('The   exit   code   is   '   +   IntToStr(ExitCode));   
      end;   
        ExitCode=cardinal
      

  2.   

    GetExitCodeThread不会返回你的TStringList值
      

  3.   

    GetExitCodeThread() 将传回线程函数的返回值,然而GetExitCodeThread() 的一个
    糟糕行为是,当线程还在进行,尚未有所谓的结束代码时,它会传回TRUE表示成功,
    如果
    这样, lpExitCode 指向的内存区域中应该放的时STILL_ACTIVE,你必须小心这种行为
    ,也就是说你不可能从其返回值中知道"到底是线程还在运行呢,还是它已经结束,但返回
    值为 STILL_ACTIVE"GetExitCodeThread() 的返回值应该是 TRUE 或者 FALSE, 尽管 BOOL 实际上是 typedef int BOOL, 即 GetExitCodeThread() 的返回值只表示该函数本身执行是否成功并不是说对应线程如果结束了GetExitCodeThread() 函数就必须返回其结束代码,线程是否结束与该函数的返回值根本就是两码事,GetExitCodeThread() 函数返回 FALSE 的唯一情况应该是它无法确定其检测线程的状态.而这里却以其返回值来判断被检测线程是否结束,并说GetExitCodeThread() 的返回值是一种" 糟糕的行为" ,这很没道理,该函数设计的目的就是获取一个线程结束时的返回值,本来就不是用来检测一个线程是否结束,当然如果能够保证线程不将 STILL_ACTIVE 作为错误码返回也可以用来检测线程是否结束.
      

  4.   


    function ThreadPro(lparam: Pointer): DWORD; stdcall;
    begin
      Result := 0;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      ThreadHandle: THandle;
      ThreadId, EixtCode: DWORD;
      IsExist: Boolean;
    begin
      ThreadHandle := CreateThread(nil, 0, @ThreadPro, nil, 0, ThreadId);  try
        IsExist := GetExitCodeThread(ThreadHandle, EixtCode);
        if IsExist then
        begin
          if ExitCode = STILL_ACTIVE then
            ShowMessage('Thread Active')
          else
            ShowMessage('Thread Function Exit');
        end
        else
          ShowMessage('Thread  Exit');  finally
        CloseHandle(ThreadHandle);
      end
      

  5.   


    function ThreadPro(lparam: Pointer): DWORD; stdcall;
    begin
      Result := 0;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      ThreadHandle: THandle;
      ThreadId, EixtCode: DWORD;
      IsExist: Boolean;
    begin
      ThreadHandle := CreateThread(nil, 0, @ThreadPro, nil, 0, ThreadId);  try
        IsExist := GetExitCodeThread(ThreadHandle, EixtCode);
        if IsExist then
        begin
          if ExitCode = STILL_ACTIVE then
            ShowMessage('Thread Active')
          else
            ShowMessage('Thread Function Exit');
        end
        else
          ShowMessage('Thread  Exit');  finally
        CloseHandle(ThreadHandle);
      end
      

  6.   

    如果你的要返回的是线程对像中的一个TStringList变量,那么很遗憾,在该线程终止的时候,线程对象会被释放,也就是你要返回的TStringList对象会给free掉,如果你的线程单纯的想将数据存进一个TStringList类型的变量返回给主线程使用,那么不妨定义一个TStringList类型的全局变量,外加适当的同步操作,或在线程终止的时候通过发送消息方式通知主线程,应该可以达到你的要求。
      

  7.   

    完善下,应该符合楼主的想法function ThreadPro(lparam: Pointer): DWORD; stdcall;
    begin
      Result := DWORD(TStringList.Create);
      with TStringList(Result) do
      begin
        Add('1');
        Add('2');
        Add('3');
        Add('4');
      end;
    end;procedure TForm1.BitBtn1Click(Sender: TObject);
    var
      ThreadHandle: THandle;
      ThreadId, EixtCode: DWORD;
    begin
      ThreadHandle := CreateThread(nil, 0, @ThreadPro, nil, 0, ThreadId);
      if ThreadHandle > 0 then
      begin
        WaitForSingleObject(ThreadHandle,INFINITE);
        if GetExitCodeThread(ThreadHandle, EixtCode) then
        begin
          if (EixtCode > 10) then
          begin
            with TStringList(EixtCode) do
              Caption := Format('Count:%d; CommandText:%s',
                [Count, CommaText]);        TStringList(EixtCode).Free;
          end;
        end;
        CloseHandle(ThreadHandle);
      end;
    end;
      

  8.   


    针对8楼的观点,我将上面的代码改动了下,经过测试,Caption中显示的释放计数是0
    ShowMessage显示出来的释放计数是1,而且,线程中创建的列表,在线程结束后,其内容依然可以被访问,所以,其占用的内存依然存在。
    所以,8楼说的是不正确的。
    在线程中创建的TStringList,在线程结束时,如果没有显示地释放,那么这个类是不会随着线程的结束而被释放。验证代码如下:
    type
      TMyList = class(TStringList)
      public
        destructor Destroy; override;
      end;var
      FreeCount: Integer = 0;
        
    { TMyList }destructor TMyList.Destroy;
    begin
      Inc(FreeCount);
      inherited;
    end;
      
    function ThreadPro(lparam: Pointer): DWORD; stdcall;
    begin
      Result := DWORD(TMyList.Create);
      with TStringList(Result) do
      begin
        Add('1');
        Add('2');
        Add('3');
        Add('4');
      end;
    end;procedure TForm1.BitBtn1Click(Sender: TObject);
    var
      ThreadHandle: THandle;
      ThreadId, EixtCode: DWORD;
    begin
      ThreadHandle := CreateThread(nil, 0, @ThreadPro, nil, 0, ThreadId);
      if ThreadHandle > 0 then
      begin
        WaitForSingleObject(ThreadHandle,INFINITE);
        if GetExitCodeThread(ThreadHandle, EixtCode) then
        begin
          if (EixtCode > 10) then
          begin
            with TStringList(EixtCode) do
              Caption := Format('FreeCount:%d; Count:%d; CommandText:%s',
                [FreeCount, Count, CommaText]);        TStringList(EixtCode).Free;
            ShowMessage(IntToStr(FreeCount));
          end;
        end;
        CloseHandle(ThreadHandle);
      end;
    end;
      

  9.   

    线程创建的时候定义1个线程上下文结构,其中包括你需要返回的TStringlist  检测到你线程退出的时候从该上下文中取你需要的结果。试试。应该能满足你的需求