【发布时间】:2011-07-08 22:23:25
【问题描述】:
我有一个应用程序在队列中使用 AutoResetEvent (WaitOne/Set) 来处理消息。我注意到当我从 Visual Studio (Shift+F5) 终止调试会话时,应用程序的原始进程会挂起(但并非总是如此)。我手动将调试器重新附加到进程,发现它有单个线程卡在 WaitHandle.WaitOne 上。
所以我的问题是,终止可能处于 WaitOne 状态的线程的正确方法是什么?
想到的第一个答案是听应用程序退出事件并在那里执行设置,但我不确定在这些调试会话之后是否可靠地调用了此事件,或者是否有我认为的更标准的做法我不知道。
作为第二个问题,对于在“生产”模式下运行的应用程序,您会以不同的方式处理这个问题吗?
【问题讨论】:
-
嗯,你手上有一个讨厌的问题。终止调试会话是使用 Windows 中可用的最大工具 TerminateProcess() 完成的。 Taskmgr.exe 中使用的相同类型的枪。只有一种可能的方式不会终止进程,内核线程很忙并且没有完成 I/O 请求。那肯定不是 AutoResetEvent。没有意义。
-
@Hans - 所以我在附加调试器后在调用堆栈中看到的 WaitHandle 不是信号的等待句柄,而是内核 i/o 任务的不同等待句柄?此任务中唯一的 i/o 是一些日志记录,这非常简单(并且只是每隔一段时间手动触发一次,而不是任何频率发生的事情)
-
我只知道你描述的没有意义。因此,如果没有任何文档,我很容易认为描述是错误的。在启用非托管调试和 Microsoft 符号服务器的情况下发布堆栈跟踪。
-
@Hans 感谢您的建议,当我回到办公室并准备好代码时会这样做。感谢您的指导。
-
我刚刚意识到我确实有另一个 I/O 操作。我疲惫的大脑完全忘记了正在读取的 TcpStream,如果我没记错的话,当我瞥了一眼我正在使用的组件时,它会在流上对 Read 进行阻塞调用。有了这个认识,以及您对更高级调试的建议,我希望在周一解决问题
标签: c# .net-4.0 waithandle autoresetevent