title: AnonymousPipeServerStream.Read() occasionally hangs on client exit
body: <p>I have a master and a slave program who interact through a pair of anonymous pipes.</p>
  
  <p>The interaction looks like this:</p>
  
  <ul>
  <li>Master creates two AnonymousPipeServerStream's</li>
  <li>Master starts client process, giving him their .GetClientHandleAsString()</li>
  <li>Master .DisposeLocalCopyOfClientHandle's both pipes</li>
  <li>Master writes stuff to one pipe and reads stuff from the other one</li>
  <li>Occasionally master forcefully terminates the slave from another thread (Process.Kill()), AND ALSO closes both pipe objects.</li>
  </ul>
  
  <p>In very rare circumstances, upon slave termination, <strong>reading from the pipe on master's side blocks indefinitely</strong> - or sometimes definitely (e.g. for several minutes). I am not able to reproduce it on my local machine, but it happens from time to time on a large cluster.</p>
  
  <p>I captured a dump of this situation, and here's what I saw:</p>
  
  <p>Stacktrace of blocked master (I am 100% sure that at this moment the client process is already terminated):</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>I also looked at the AnonymousPipeServerStream object that's blocking, and at its state and handle.</p>
  
  <p>It has:</p>
  
  <ul>
  <li>m_state = 4 (i.e. closed)</li>
  <li>m_clientHandle is a closed handle (according to SafeHandle._state and to the output of !handle)</li>
  <li>m_handle is an open handle, with _state = 6 (i.e. NOT closed, even though the Pipe object is closed and, according to decompilation, it should have called m_handle.Dispose()):</li>
  </ul>
  
  <p>Here's the output of !handle for the master-side handle.</p>
  
  <pre><code>0:000&gt; !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
  </code></pre>
  
  <p>I am a bit worried that the HandleCount is 2 and PointerCount is 5.</p>
  
  <p>Any ideas what could have gone wrong? Why was the master's end of the reading handle not closed when I closed the pipe? Why was the pipe not broken, despite the client termination and despite the fact I called DisposeLocalCopyOfClientHandle?</p>
  
  <p>What can I do to at least work around this? Maybe just do Thread.Interrupt on the reading thread?..</p>