关于线程的一个问题,请指教。(在线等待)(100分)

  • 主题发起人 主题发起人 crazycock
  • 开始时间 开始时间
C

crazycock

Unregistered / Unconfirmed
GUEST, unregistred user!
一个主程序,用了多个线程进行UDP传输,当关闭主程序的时候,可能有多个线程还没有结束,因为线程中直接访问了主窗口MainForm的资源,所以MainForm.Close的时候会发生错误,如果在MainForm.onClose里面显示一个Showmessage('hello'),等1秒多然后点OK,就不会发生异常(因为线程中的工作通常1秒内可以完成)。
问:
(1)如何避免在主窗口需要关闭的时候,不会发生异常?
(2)能否主动在窗口关闭之前释放所有线程,怎么完成?
在线等待。
 
调用线程的结束方法,实现设置 freeOnTerminate := true
 
这个问题我也碰过啊,你在关闭主窗体之前一定要一个处理措施:等待所以子线程的结束。有时哪怕你挂起子线程,然后强制去Terminate都不行。因为在这前面的UDP命令已经发出去了,也即是说已经在使用程序中其它资源了。这时唯一方法就是虽等待它结束了。
你可以将多个线程存放在一个TLIST中,然后在退出前判断各个线程是否已结束,还有没结束者,等待!全部结束后再关闭主窗体。
 
xwings:你的方法我用了。目前就是这样做的,可是不行。就像forsoft说的情况一样。
forsoft:我现在就是只能等待,可是我还想主动释放他们,555555~~哭啊~~为什么不可以释放~
 
不好意思,没看清题目是UDP传输,弄错了
 
能否告诉我,是否能在主程序里面释放线程,然后再关闭主程序?
 
呵呵,我也想能主动释放啊,强制关掉有时一点问题也没有,但有时正在使用系统资源(Windows本身的kernel的话)强制关掉会报错的,这个Delphi本身都不可能解决的。Delphi退出时为什么窗体隐藏了,但进程中还有Delphi32.exe驻留好一会,我想也是这个原因。上星期我写了一个使用系统API机制的东西,开了5个线程跑,有时退出时Terminate就报错;我跟进去汇编代码一看:那些API已经在使用系统内存资源了,命令已发出去,这时根本关不了线程,虽然Terminate也运行过,但退出时就是报。后来我将所有线程句柄存放在TLIST中,退出时判断处理就行了。在所开的线程中,你可以重复利用各个空闲的线程,这处机制非常好。
现在我把线程数开到200都没问题(但有的系统版本不能开太大,这个要注意:))。
 
procedure Terminate;
var
xStart:Cardinal;
begin
{等待指定时间后强行结束线程}
xStart:=GetTickCount;
while WaitForSingleObject(YourThread.Handle, 10) = WAIT_TIMEOUTdo
begin
Application.ProcessMessages;
if GetTickCount > (xStart + 4000) then
begin
TerminateThread(YourThread.Handle, 0);
Break;
end;
end;
end;
 
谢谢xwings指点。
问一下,我能否通过查找的方式得到目前正在运行的Thread的handle?
就比如FindComponent?可以么?
 
把创建的线程句柄加入到一个list中,这是最简单的做法。
 
线程的结束方法Terminate只是将Terminated属性设置为true,不结束线程
在主窗口中结束线程,我通常这么做:
AThread.Terminated;
AThread.WaitFor;
AThread.Free;
还没出现过问题。当然线程中对Terminated的改变响应要快,否则可能导致主线程死掉
 
哈哈~~搞定了,我也是这么想来者~我把Handle都放到一个StringList里面了。然后退出前检查里面的内容,逐个TerminateThread。
不过我看了《Delphi5开发人员指南》里面308页的内容,说
“某些情况下,你可以使用Win32 API函数TerminateThread()来终止一个线程。但是除非没有别的办法了,否则不要用它。………………”
“如果选用这个函数,应该考虑到它的负面影响。首先,此函数在Windows NT与在Windows95/98下并不相同。在Windows95/98下,这个函数能够自动清除线程所占用的栈;而在Windows NT下,在进程被终止前栈仍然保留。其次,无论线程代码中是否有try...finally块,这个函数都会使线程立刻停止执行。这意味着,被线程打开的文件没有被关闭(注:我的程序没有打开文件,无所谓)、由线程申请的内存没有被释放等情况。……”
---你如果也有《Delphi5开发人员指南》的话,你看一下308页介绍的,我不清楚2000是否能够很安全的释放资源,不清楚会有什么不良后果,我只知道,目前确实程序安全退出了,没有发生异常。
希望xwings能再次指点,谢谢~
 
为了兼容性,所以要你在terminateThread之前检测Handle是否释放掉。超时之后再用这个函数吧。
 
首先要确保你的线程在循环. 然后主线程中设置线程的terminated := true
线程检测到之后应该正常退出.即可
如果可能会有没有响应的情况的话,使用上面给你的函数中的方法,调用waitForSingleObject等待一定时间.然后超时再调用 terminatedthread
 
再次感谢。
 
后退
顶部