.NET IpcChannel 无法可靠地正确清理?
由于某种原因,在使用 IpcChannel 并将其关闭后,有时命名管道会保持打开状态,并有一个线程在等待它。我无法在调试环境中按需实现这种情况,但在我们的生产环境中每天会发生 5 到 10 次。这样做的坏影响是它阻止我卸载应用程序域,因为有一个线程在命名管道上无限等待(在本机方法中)...我的代码中没有调用堆栈上的框架 - 它是一个内部 .网线程。如果我启动进程资源管理器并找到保持打开状态的命名管道句柄并强制关闭它,那么一切都会再次变得愉快,应用程序域会正常卸载。我可能做错了什么,因为我没有大量使用 IpcChannels....我的服务器端代码在这里: http://pastebin.com/f6e2583b9 如果有人想看一眼....它正在完全修补的 Server2003/.NET 2.0 上运行。
作为一种丑陋的解决方法,我想我将跟踪我创建的每个通道,然后定期检查以确保它们正确关闭,然后在应用程序域卸载时我将强制关闭任何悬空的管道...... .任何人都可以指出我如何做到这一点的正确方向吗?我知道管道的名称...但我不知道如何检查它是否仍然打开,或者如何关闭任何现有的句柄...
For some reason, after using an IpcChannel and shutting it down, sometimes the namedpipe stays open, with a thread waiting on it. I cannot make this happen on demand in a debug environment, but it happens 5 to 10 times per day in our production environment. The bad effect this is having is that it is stopping me from unloading the appdomain as there is a thread waiting infinitely on the named pipe (in a native method)...no frame on the callstack is in my code - it's an internal .net thread. If I fire up process explorer and find the named pipe handle that was left open and forcefully close it then it all becomes happy again, the appdomain unloads fine. It's possible I'm doing something wrong as I haven't worked with IpcChannels a whole lot....my server-side code is here: http://pastebin.com/f6e2583b9 if anyone wants to take a peek....this is running on fully patched Server2003/.NET 2.0.
As an ugly-ass workaround, I'm thinking I'll track every channel I create and then periodically check to make sure they shut down properly, and then on appdomain unload I'll forcefully close any pipes which are left hanging....can anyone point me in the right direction as to how I could do this? I know the name of the pipe....but I'm not sure how to check if it's still open, or how to close any existing handles...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,我以前见过这个。
当客户端仍然打开 IPC 通道时,IPC 也会发生类似的情况:服务器将无法关闭并再次打开它,因为它已被客户端使用。
要解决这些问题,建议的方法是将所有 IPC 服务器通道创建放在子
AppDomain
中。然后,当您希望关闭它时,只需执行
Close()
通常的“良好”关闭过程,然后执行AppDomain
卸载即可。这将用核武器消灭任何剩余的东西。
它将删除任何与 IPC 相关的内容,并会因为客户端占用 IPC 通道而对客户端进行攻击;)
Yes, I've seen this before.
A similar thing can occur with IPC when the client still has the IPC channel open: The server will not be able to close and open it again because it's already in use by the client.
To get around these problems, the recommended way is to place all IPC server channel creation in a child
AppDomain
.Then when you wish to shut it down, you merely perform the usual 'nice' shutdown procedures of
Close()
followed by anAppDomain
Unload.This will nuke any left overs.
It will remove any IPC related stuff as well as kick the client in the head for hogging the IPC channel ;)