[Delphi]DELPHI线程的终止和退出
在 Delphi中使用线程,当窗体关闭时,如果窗体中启用了线程,一般需要手动 关闭,以释放资源。 常用来结束线程的代码为: PcmThrd.Terminate; PcmThrd.WaitFor; 即先触发 Terminate方法,然后等待线程的结束。 这种方法要求线程不能使用 FreeOnTerminate := True; ,否则在 WaitFor即将 结束的时候会引发“无效句柄”的错误。 这种方法在窗体关闭的时候会等待一段事件(因为 WaitFor)。 因此,如果不是在主窗体中结束线程时,其实我们可以不必使用 WaitFor。而是 采用如下方法: 将 FreeOnTerminate := True; 这样在窗体关闭的代码中直接调用 PcmThrd.Terminate; 即可。 注意: 如果设置了 PcmThrd.OnTerminate := SomeFunction; 那么在调用 PcmThrd.Terminate;前尽量将 PcmThrd.OnTerminate := nil,以免 结束线程后 SomeFunction中的变量出现空指针错误。当然,这不是绝对的,需 要根据具体程序而定 DELPHI 线程的终止和退出 1)自动退出: 一个线程从 cute()过程中退出,即意味着线程的终止,此时将调用 windows 的 exitthread()函数来清除线程所占用的堆栈。 如果线程对象的 freeonterminate 属性设为 true,则线程对象将自动删除,并释放线 程所占用的资源。 这是消除线程对象最简单的办法。 2)受控退出: 利用线程对象的 terminate 属性,可以由进程或者由其他线程控制线程的退出。只需 要简单的调用该线程的 terminate 方法,并设直线程对象的 terminate 属性为 true。 在线程中, 应该不断监视 terminate 的值, 一旦发现为 true, 则退出, 例如在 cute() 过程中可以这样写: while not terminated do begin end; 3)退出的 api 函数: 关于线程退出的 api 函数声明如下:code function terminatethread(hthread:thandle;dwexitcode:dword); 不过,这个函数会使代码立刻终止,而不管程序中有没有 tryfinally 机制,可能会导致错误,不到万不得已,最好不要使用。 4) 利用挂起线程的方法(suspend) 利用挂起线程的 suspend 方法,后面跟个 free,也可以释放线程,例如: thread1.suspend; //挂起 thread2.free; //释放 遇到的“ Code:1400 无效窗口句柄 “的问题,关闭不了程序 最近写程序,遇到的“ Code:1400 无效窗口句柄 “的问题,关闭不了程序?! 似乎是在线程里调用了主窗体的东西,使得释放的先后次序被打乱了,所以句柄 有问题! 但是要找到问题的根源太麻烦了,这时有招必杀技! 大家要记好了,有类似的无法关闭程序的问题,一句搞定! ExitProcess(0); 简单的说就是终止自己的进程!虽然是暴力了一点,但是绝对有效! 但是这种方法不会触发 onclose之类的事件,可以说是不触发任何事件,无痛无 痒地结束了进程,干净利落,所以要记得在结束之前保存必要的数据,做必要的 操作, 最好是释放一下内存, 在 Win下结束进程是非常不干净的, 会有内存残留。 获取线程状态 Function CheckThreadFreed(aThread: TThread): Byte; var i: DWord; IsQuit: Boolean; begin if Assigned(aThread) then begin IsQuit := GetExitCodeThread(aThread.Handle, i); if IsQuit then //If the function succeeds, the return value is nonzero. //If the function fails, the return value is zero. begin if i = STILL_ACTIVE then //If the specified thread has not terminated, //the termination status returned is STILL_ACTIVE. Result := 1 else Result := 2; //aThread未 Free,因为 Tthread.Destroy 中有执行语句 end else Result := 0; //可以用 GetLastError取得错误代码 end else Result := 3; end; 快速关闭线程 //=========ThrdMain.pas================== Var hEventDead:Thandle; constructor ThrdMain.Create; begin hEventDead := CreateEvent(0,true,False,‘SMSdesktop‘);//创建对象事件 inherited Create(False); end; //创建对象关闭事件 function ThrdMain.WaitEventDead: Boolean; begin //创建线程 var Thread_Main:ThrdMain ;(调用自我创建的线程对象) Thread_Main:=ThrdMain.Create ; //关闭线程 Thread_Main.WaitEventDead ; Thread_Main.WaitFor ; //=========ThrdMain.pas================== var hEventDead:Thandle; constructor ThrdMain.Create; begin hEventDead := CreateEvent(0,true,False,‘SMSdesktop‘);//创建对象事件 inherited Create(False); end; //创建对象关闭事件 function ThrdMain.WaitEventDead: Boolean; begin Gbl_ReadSMS:=False; WaitForSingleObject(hEventDead,500);//表示在 0.5 秒内强制关闭 end; 多线程的检查,与关闭线程 procedure TDemoThread.cute; begin inherited; if Assigned(FOnHintText) then FOnHintText(Self); end; procedure T1.ShowThreadDemo(Se