问题1:关于线程的创建
我使用的创建方法是:
Thread1 = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;
然后在Thread1.Execute中写实现过程,直接使用Thread1.create创建
那么这样创建的话我能获取创建线程的句柄吗?如果我想要强制关闭此线程该怎么办??问题2:线程强制终止会有什么影响??问题3:terminatethread和terminate函数怎样终止线程??假如线程在while循环中,能终止吗?总共3个问题,一个50分,希望各位大神帮我解惑,谢谢了

解决方案 »

  1.   

    我的想法是在主界面里声明全局线程对象变量,这样随时可以用这个实例。启动线程后,如果需要中断,则在线程的EXECUTE方法里的循环体中增加判断,如果被打断则跳出。
      

  2.   

    type
      TTdownLoadThread = class(TThread)
      protected
         procedure Execute:override;
      end;
    ...
    var
       tDownLoad : TTdownLoadThread;
    ....implementation
    procedure TForm1.Button1Click(Sender:TObject);
    begin
       tDownLoad := TTdownLoadThread.create(false);
       ...
       tDownLoad .resume;
    end;..........
    procedure TTdownLoadThread.Execute;
    begin
       FreeOnTerminate := true; 
        while xxx do
       begin
          if 被打断 then break;//这里不会写了。    end;
    end;
      

  3.   

    while not Terminated do
    ...
      

  4.   

    给一个实例,仅代参考:
    unit LongWaitTrd;interfaceuses  Classes,Windows,Messages,SyncObjs;type  TLongWaitTrd = class(TThread)
            private
              FMainWin:THandle;  
              QuitEvent: TEvent; 
              procedure  SendFeedBackToMainWin();
              procedure  DoTheHardWork();       
            protected
              procedure Execute; override;
            public
              constructor  Create(CreateSuspended: Boolean); destructor   Destroy; override;
              function  ExitLongWaitTrd():Boolean;
            published
              property MainWin:THandle read FMainWin write FMainWin;
          end;implementationuses Unit1;constructor TLongWaitTrd.Create(CreateSuspended: Boolean);
    begin
      inherited Create(CreateSuspended);
    end;destructor TLongWaitTrd.Destroy;
    begin
      inherited;
    end;procedure TLongWaitTrd.DoTheHardWork();
    begin 
      //to do  
    end;procedure TLongWaitTrd.Execute;
    var Msg: TMsg;
    begin
      FreeOnTerminate:=True;
    //  1.长等待型线程示例
    //  while GetMessage(Msg, 0, 0, 0) do
    //  begin
    //    if (Msg.message=WM_USER+1000) then //任务来了
    //    begin
    //      DoTheHardWork();
    //      SendFeedBackToMainWin;
    //    end;
    //    if (Msg.message=WM_QUIT) then
    //    begin
    //      QuitEvent.SetEvent;
    //      Break; 
    //    end;
    //  end;
    //  2.长工作型线程示例
    //  while(true) do
    //  begin
    //    if  PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
    //    begin
    //      if (Msg.message=WM_QUIT) then 
    //      begin
    //        QuitEvent.SetEvent;
    //        Break;
    //      end;
    //    end;
    //    DoTheHardWork();
    //  end;
    end;function TLongWaitTrd.ExitLongWaitTrd;
    begin
      Result:=true;
      QuitEvent:=TEvent.Create(nil,True,False,'QuitEvent');
      PostThreadMessage(ThreadID,WM_QUIT,0,0);
      if  (QuitEvent.WaitFor(2000)=wrTimeOut) then
        Result:=false;
      QuitEvent.Free ;
    end;procedure TLongWaitTrd.SendFeedBackToMainWin();
    var  Status:String;
    begin
      if (MainWin<>0) then
      begin
        Status:='The data has been processed by thread.';
        PostMessage(MainWin,WM_USER+2000,0,Integer(Status))
      end;
    end;end. 
      

  5.   

    感谢各位大神,关于标志位让线程退出的方法我早就用过了,只是某些特殊情况下不太好用,比如我在线程中接收TCP收到的消息,使用控件接收是阻塞方式,或者后面需要大量时间来处理其他函数,那么,循环回来判断标志位中间时间间隔就有点太长了,所以在想强制线程退出的方法,还有强制线程退出有什么缺陷或者不好的影响吗??
      

  6.   

    关于4楼的例子,由于我对消息的方式不太了解,所以还没有尝试,不过我创建线程的方式不是直接用API函数,所以没办法得到句柄,还有其他好办法吗??顺便给我讲讲强制结束线程会有什么不好吧!!!
      

  7.   

    windows上线程对象的Handle就是句柄
      

  8.   

    SOCK阻塞的事情,同问。 我知道JAVA的,同样的问题,线程组赛后无法中断,后来改为Netty了事。delphi有没有类似的框架?
      

  9.   

    常用的就是while中判断Terminated属性
      

  10.   

    在主线程单元中设置一个bStop:Boolean;初始化为False;在线程循环中能访问bStop,if bStop then break;就跳出循环了,Execute可以结束了。。一般用这种方式结束线程比较好吧,“自然”结束,当然你也可以暴力结束,主线程中设置一个变量th1:Thread1,这个变量在建立线程的时候用来记录线程数据,需要暴力结束的时候,直接用th1.Terminate
      

  11.   

    我习惯这么弄TTestThread = class(TThread)
      private
        FlagEnd: Boolean;
      public
        procedure Execute; override;
        procedure FreeSelf;
      end;procedure TTestThread.Execute;
    begin
      inherited;
      while not FlagEnd and not Terminated do
      begin
        //TODO: 
      end;
    end;procedure TTestThread.FreeSelf;
    begin
      FlagEnd := True;
      Self.Free;
    end;