在另一个窗体中建立了一个线程CircleThread,这个线程创建后休眠,需要resume后才能执行。然后,
if not Assigned(CircleThread) then
CircleThread := TCircleThread.Create(2, 2, 2, '2', '2'); 这种情况能OK
else begin
CircleThread.X := 1; 这种情况不能执行
CircleThread.Y := 1;
CircleThread.radius := 1;
CircleThread.color := '1';
CircleThread.ADeviceNo := '1';
end;
CircleThread.Resume;现在,没有线程创建线程后执行时是正确的;
但是线程已存在时,线程都不执行;
是哪里有问题,不是写了CircleThread.Resume用来唤醒线程了吗?
if not Assigned(CircleThread) then
CircleThread := TCircleThread.Create(2, 2, 2, '2', '2'); 这种情况能OK
else begin
CircleThread.X := 1; 这种情况不能执行
CircleThread.Y := 1;
CircleThread.radius := 1;
CircleThread.color := '1';
CircleThread.ADeviceNo := '1';
end;
CircleThread.Resume;现在,没有线程创建线程后执行时是正确的;
但是线程已存在时,线程都不执行;
是哪里有问题,不是写了CircleThread.Resume用来唤醒线程了吗?
解决方案 »
- RichEdit控件滚动条
- 高手们帮帮我啊
- rave 分页 合计
- 如何在程序运行时修改StringGrid的goRowSelect值?在线守候。
- 怎样删除正在运行的程序?急用.敬请各位能给予帮助.
- 请大家提供几个免费数据库的例子.
- 弱智问题:怎样在DELPHI5把SQL SEVER中某一数据库中的各个表的数据,导出为纯文本格式???
- Tregistry对象的WriteBinaryData方法的第2、3个参数到底是干什么用的?
- 系统启动问题
- 请问如何让一个Form Create 之后,ListBox1.SetFocous;然后再自动选中其中一个Item?
- ●那位大哥能救救我呀,如何让我写的IEHELPER只在启动IE的时候加载,启动文件浏览器什么的不加载
- 做一IE监测的程序,是不是2000和XP的IE不同啊,在2000下能运行,在XP下不能运行,查了很长时间不知道什么问题啊
就是说你的线程第一次执行完就退出了
再Resume当然没有效果了
来取得ExitCode,如果ExitCode=STILL_ACTIVE
表示线程还存在,对于存在的线程,则可以使用ResumeThread(ThreadHandle)来唤醒线程,如果线程仍然处于运行状态,则会返回错误具体的自己去看相关的API的返回值。
begin
AlarmCircleThread := TAlarmCircleThread.Create(2, 2, 2, '2', '2');
AlarmCircleThread.Resume;
end
else begin
IsLay :=GetExitCodeThread(AlarmCircleThread.Handle,ExitCode);
if IsLay then begin
if ExitCode=STILL_ACTIVE then begin
ResumeThread(AlarmCircleThread.Handle);
showmessage('线程在活动中')
end
else
showmessage('线程已终止terminate,但句柄未释放free');
end
else begin
CloseHandle(AlarmCircleThread.Handle);
showmessage('句柄已释放'); end;
ShowMessage('线程对象还存在');
end;
我是这样写的,但是还不能达到效果:(
一、该线程对象不存在(Not Assigned),那么就需要明确是否需要再创建该线程对象,如果不需要,可能得抛出异常,给操作员或者主操作函数/过程一个异常(Exception);
二、该线程对象存在但是线程执行体已经结束执行,此时就需要进行CloseHandle(实际上使用TThread,应该是调用Free方法),之后同情况一一致处理;
三、该线程确实处于睡眠(Sleep,Suspended)状态,则直接调用ResumeThread(对于使用TThread类,包括子类对象应当调用其自身的Resume方法),通常Resume也并不一定会成功,则对于使用ResumeThread,则可以根据返回值进行处理,但是对于使用TThread.Resume,则另做处理,通常情况下都会认为它是成功的,这里得看个人的严谨态度,同时也视程序的可靠性要求而来,可靠性要求越高,则更需要注意各种异常的判断,特别是任何一个有返回值的函数调用都需要对返回值进行判断并加以处理,这也是一个习惯问题。对于没有返回值的过程调用通常会认为是必定成功的,但是也要视情况而定,必要时尽可能通过其它途径进行异常检验,以避免不必要的问题发生,并且通常在这种过程的调用出现问题是最能进行debug的。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;