首先要明确,当线程处于Sleep(Suspended)状态下时,你需要唤醒(Resume),但是此时可能存在三种情况:
一、该线程对象不存在(Not Assigned),那么就需要明确是否需要再创建该线程对象,如果不需要,可能得抛出异常,给操作员或者主操作函数/过程一个异常(Exception);
二、该线程对象存在但是线程执行体已经结束执行,此时就需要进行CloseHandle(实际上使用TThread,应该是调用Free方法),之后同情况一一致处理;
三、该线程确实处于睡眠(Sleep,Suspended)状态,则直接调用ResumeThread(对于使用TThread类,包括子类对象应当调用其自身的Resume方法),通常Resume也并不一定会成功,则对于使用ResumeThread,则可以根据返回值进行处理,但是对于使用TThread.Resume,则另做处理,通常情况下都会认为它是成功的,这里得看个人的严谨态度,同时也视程序的可靠性要求而来,可靠性要求越高,则更需要注意各种异常的判断,特别是任何一个有返回值的函数调用都需要对返回值进行判断并加以处理,这也是一个习惯问题。对于没有返回值的过程调用通常会认为是必定成功的,但是也要视情况而定,必要时尽可能通过其它途径进行异常检验,以避免不必要的问题发生,并且通常在这种过程的调用出现问题是最能进行debug的。
Code
if not Assigned(AlarmCircleThread) then
begin
AlarmCircleThread := TAlarmCircleThread.Create(2, 2, 2, '2', '2');
AlarmCircleThread.Resume; //这里使用了Resume说明TAlarmCircleThread创建时是处于睡眠状态的
end
else
begin //线程对象仍然存在
IsLay := GetExitCodeThread(AlarmCircleThread.Handle, ExitCode);
if IsLay then
begin
if ExitCode = STILL_ACTIVE then
begin
ResumeThread(AlarmCircleThread.Handle); //这里该使用AlarmCircleThread.Resume;
showmessage('线程在活动中')
end
else
showmessage('线程已终止terminate,但句柄未释放free'); //这里由于线程的执行过程已经结束,华伦再世也无法让它起死回生,所以就该让它安静地去
//Begin=====================Modify
AlarmCircleThread.Free;
AlarmCircleThread := TAlarmCircleThread.Create(2, 2, 2, '2', '2');
AlarmCircleThread.Resume;
//End=======================Modify
end
else
begin
//CloseHandle(AlarmCircleThread.Handle);//这里面不该是关闭句柄,这里是由于调用GetExitCodeThread失败而引发的,所以应当使用GetLastError来判断所产生的错误
//showmessage('句柄已释放');
//Begin=====================Modify
raise
Exception.CreateFmt('Error occured when call GetExitCodeThread! ThreadID:%d,Error Code:%d', [AlarmCircleThread.ThreadID, GetLastError]);
//End=======================Modify
end;
//ShowMessage('线程对象还存在');
end;