AnonymousPipeServerStream.Read()偶尔会在客户端出口挂起
本文关键字:客户端 出口 挂起 偶尔 Read AnonymousPipeServerStream | 更新日期: 2023-09-27 18:18:56
我有一个主程序和一个从程序,它们通过一对匿名管道交互。
交互作用如下:
- Master创建两个AnonymousPipeServerStream
- 主启动客户端进程,给他。getclienthandleasstring ()
- Master .DisposeLocalCopyOfClientHandle的两个管道
- Master向一个管道写入内容,并从另一个管道读取内容
- 偶尔主线程从另一个线程强制终止从线程(Process.Kill()),同时关闭两个管道对象。
在非常罕见的情况下,在从端终止时,从主端的管道读取会无限期阻塞,或者有时会阻塞(例如几分钟)。我无法在我的本地机器上重现它,但在大型集群上有时会发生这种情况。
我捕获了这种情况的转储,下面是我看到的:
阻塞主进程的堆栈跟踪(我100%确定此时客户端进程已经终止):
000000000c83e488 000000007700fdba [NDirectMethodFrameStandalone: 000000000c83e488] Microsoft.Win32.UnsafeNativeMethods.ReadFile(Microsoft.Win32.SafeHandles.SafePipeHandle, Byte*, Int32, Int32 ByRef, IntPtr)
000000000c83e430 000007feeab32820 DomainBoundILStubClass.IL_STUB_PInvoke(Microsoft.Win32.SafeHandles.SafePipeHandle, Byte*, Int32, Int32 ByRef, IntPtr)*** WARNING: Unable to verify checksum for System.Core.ni.dll
000000000c83e540 000007feeac14574 System.IO.Pipes.PipeStream.ReadFileNative(Microsoft.Win32.SafeHandles.SafePipeHandle, Byte[], Int32, Int32, System.Threading.NativeOverlapped*, Int32 ByRef)
000000000c83e5a0 000007feeac14a23 System.IO.Pipes.PipeStream.ReadCore(Byte[], Int32, Int32)
000000000c83e610 000007fef0169d8f System.IO.BinaryReader.FillBuffer(Int32)
000000000c83e650 000007fef0169c8a System.IO.BinaryReader.ReadInt32()
我还查看了阻塞的AnonymousPipeServerStream对象,以及它的状态和句柄。
它:
- m_state = 4(即关闭)
- m_clientHandle是一个关闭句柄(根据SafeHandle)。_state和输出!handle)
- m_handle是一个打开的句柄,_state = 6(即未关闭,即使Pipe对象是关闭的,根据反编译,它应该调用m_handle. dispose ()):
这是主端句柄的!句柄的输出。
0:000> !handle 1850 ff
Handle 0000000000001850
Type File
Attributes 0
GrantedAccess 0x120189:
ReadControl,Synch
Read/List,ReadEA,ReadAttr,WriteAttr
HandleCount 2
PointerCount 5
No object specific information available
我有点担心HandleCount是2,而PointerCount是5。
你知道哪里出了问题吗?为什么当我关闭管道的时候,阅读手柄的主端没有关闭?为什么管道没有破裂,尽管客户端终止,尽管我调用了DisposeLocalCopyOfClientHandle?
我能做些什么来解决这个问题?也许只做Thread。
主进程中可能的事件顺序,前面是线程号:
- 1 -即将调用Microsoft.Win32.UnsafeNativeMethods。ReadFile (inside BinaryReader.ReadInt32)
- 2 -终止从进程并关闭管道句柄
- 3 - win32管道句柄(现在关闭)被重用用于其他管道(或文件或任何)
- 1 - Microsoft.Win32.UnsafeNativeMethods。ReadFile使用旧句柄开始读取,该句柄现在指向其他对象,并阻塞。
修复:
杀死线程2中的从属进程,但不关闭句柄。这将导致线程1中的任何读取终止,然后关闭线程1中的管道句柄。
道德:不要在使用句柄时关闭它们