У меня есть ведущая и подчиненная программы, которые взаимодействуют через пару анонимных каналов.
Взаимодействие выглядит так:
- Мастер создает два объекта AnonymousPipeServerStream
- Мастер запускает клиентский процесс, давая ему свои .GetClientHandleAsString ()
- Мастер. Оба канала .DisposeLocalCopyOfClientHandle
- Мастер записывает материал в один канал и читает материал из другого
- Иногдамастер принудительно завершает работу ведомого из другого потока (Process.Kill ()), И ТАКЖЕ закрывает оба объекта канала.
В очень редких случаях, после завершения работы ведомого, чтение из канала на ведущем устройствебоковые блоки на неопределенный срок - или иногда определенно (например, на несколько минут).Я не могу воспроизвести его на своей локальной машине, но это происходит время от времени на большом кластере.
Я захватил дамп этой ситуации, и вот что я увидел:
Stacktrace заблокированного мастера (я на 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 ()):
Вот вывод! Handle для маркера на стороне мастера.
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.Interrupt в теме чтения? ..