如何停止无响应线程 [英] How to stop a non responsive thread

查看:150
本文介绍了如何停止无响应线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文件传输应用程序,可以在FTP服务器之间移动文件.就像任何时候一样,我们可以移动数十个文件.为了防止FTP服务器泛滥,我有一个监视和信号锁定系统.

我的FTP客户端经常根据调用堆栈冻结在System.Net.Sockets.Socket.Receive()中的某个位置.我没有例外,所以不能解决这个问题.我想取消该线程,因为它阻止了其他想要使用FTP客户端的线程.

我已经考虑过启动最终在新线程中调用System.Net.Sockets.Socket.Receive()的方法,并在一段时间后中止该线程,但我担心套接字在一个线程后仍将保持打开状态中止.在没有响应的线程之后,有没有更优雅的方式来杀死和清理?

解决方案

否.没有线程的合作,没有安全,可靠的方式杀死线程.现有的机制可能是很笨拙的,和/或不一定奏效.

  • 您可以尝试Interrupt()另一个线程,但这通常只会中断正在等待/睡眠或正在执行可能会阻塞的线程.如果它位于不涉及阻塞的中间,它甚至不会看到,更不用说响应了,直到它再次阻塞为止.如果您的流氓线程很可能是永不".
  • Abort()可能杀死线程,但也不保证-线程会顽固地拒绝死亡.即使它确实死了,它也可能使您的应用程序域处于可疑状态. (假定线程在进入finally块时就中止了.然后将在该处抛出一个异常,并且该finally块将不会运行-因此它将释放的所有内容(锁,本机资源等)将保持未发布状态.)
  • 显然,即使卸载应用程序域也只是中止了其中的线程,所以Thread.Abort的不确定性适用-此外,如果可行,它还会杀死应用程序域中的每个线程.
  • 关于相对安全并保证能正常工作的唯一事情是杀死整个过程.而且,如果您这样做,就无法保证外部事物的状态.您只能保证所拥有的任何资源都将被释放/关闭/无论如何,而不是它们处于任何特定状态(例如未中断").

在这种情况下,更好的解决方案可能是异步接收(使用真正的异步内容(ReceiveAsync),而不是BeginReceive/EndReceive).这样一来,线程就不会在本地对象中被阻塞,并且更容易被中断(如果由于某些原因您仍然必须这样做;异步的好处包括您甚至不需要单独的线程来监视输入).

I have a file transport application that moves files between FTP servers. As any one time we can have dozens of files on the move. In order to prevent flooding the FTP servers I have a system of monitor and semaphore locks.

Every so often my FTP client freezes somewhere inside System.Net.Sockets.Socket.Receive() according to the call stack. I don't get an exception so can't deal with the problem. I'd like to cancel the thread as it is blocking other threads that want to use the FTP client.

I've considered starting the method that eventually calls System.Net.Sockets.Socket.Receive() in a new thread and aborting the thread after a time period but I'm concerned that the sockets will remain open after a thread abort. Is there a more gracefull way to kill and clean up after a non responsive thread?

解决方案

No. There's no safe, reliable way to kill a thread without its cooperation. The mechanisms that exist can be quite heavy-handed, and/or just don't necessarily work.

  • You can attempt to Interrupt() the other thread, but that generally only interrupts a thread that's waiting/sleeping or is doing something that could block. If it's in the middle of something that doesn't involve blocking, it won't even see, much less respond to, the interrupt til it tries to block again. Which, if you have a rogue thread, may very well be "never".
  • Abort() will probably kill a thread, but it is not guaranteed either -- the thread can stubbornly refuse to die. And even if it does die, it can leave your app domain in a questionable state. (Suppose the thread is aborted just as it entered a finally block. An exception will be thrown right then and there, and that finally block won't run -- so anything it'd release (locks, native resources, whatever) will remain unreleased.)
  • Apparently even unloading the app domain just aborts the threads in it, so the uncertainties of Thread.Abort apply -- plus, if it works, it'll also kill every thread in the app domain.
  • About the only thing that's relatively safe and guaranteed to work is to kill the entire process. And if you do that, there's no guarantee about the state of external stuff. You can just guarantee that any resources held will be released/closed/whatever, not that they're in any particular state (like, say, "uncorrupted").

In this case, a better solution might be to receive asynchronously (using the real async stuff (ReceiveAsync), not BeginReceive/EndReceive). That way the thread isn't blocked in native stuff, and is more easily interruptible (if for some reason you still have to do that; async's benefits include that you don't even need a separate thread just to watch input).

这篇关于如何停止无响应线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆