WCF 命名管道 IO 异常 - 管道已结束。 (109, 0x6d)

Posted

技术标签:

【中文标题】WCF 命名管道 IO 异常 - 管道已结束。 (109, 0x6d)【英文标题】:WCF Named Pipe IO Exception - The pipe has been ended. (109, 0x6d) 【发布时间】:2015-01-20 11:23:15 【问题描述】:

我们有一个 WCF 服务,它在启动时通过 Net.Pipes 协议调用其他几个服务。该调用返回一个字符串列表,没有枚举或复杂对象

有时,我们会收到以下异常。

    System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d). ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d). ---> System.IO.PipeException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d).
   at System.ServiceModel.Channels.PipeConnection.FinishSyncRead(Boolean traceExceptionsAsErrors)
   at System.ServiceModel.Channels.PipeConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   --- End of inner exception stack trace ---
   at System.ServiceModel.Channels.PipeConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   at System.ServiceModel.Channels.ConnectionStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Security.NegotiateStream.StartFrameHeader(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.NegotiateStream.StartReading(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   --- End of inner exception stack trace ---
   at System.Net.Security.NegotiateStream.ProcessRead(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.NegotiateStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.ServiceModel.Channels.StreamConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   --- End of inner exception stack trace ---

它不会每次都发生。我几乎找不到任何关于此错误的引用。

我想知道,为什么会发生这种情况以及如何预防。

【问题讨论】:

你是否使用 [KnownType] 属性来装饰你的数据合约? 【参考方案1】:

一个可能的原因是,当 Web 服务尝试执行其工作时,您的应用程序池正在回收。

将其配置为在特定时间运行:

打开 IIS 管理器。

在“连接”窗格中,展开服务器节点并单击“应用程序” 游泳池。

在应用程序池页面上,选择一个应用程序池,然后 单击“操作”窗格中的“回收”。

选择特定时间,然后在相应的框中键入时间 您希望应用程序池每天回收。例如, 输入上午 11:30 或晚上 11:30。

另一个原因可能是您的消息负载太大。增加服务器和客户端的连接关闭时间。顺便说一句,超时可能不仅因为消息大小,还因为系统太忙(一段时间 CPU 处于 100%)或者因为服务启动需要太多时间(在这种情况下预编译可能会有所帮助)。

为您的应用程序配置跟踪可能有助于诊断问题:https://msdn.microsoft.com/en-us/library/ms733025.aspx

【讨论】:

这个想法很有趣,我会检查一下。【参考方案2】:

为什么会这样?

正如错误所说:在读取操作有机会运行之前管道已关闭。

如何预防?

不要关闭句柄。可以通过几种方式关闭句柄:

如果调用了Abort() 函数。 如果调用了Close() 函数。 如果调用了DuplicateAndClose() 函数。

【讨论】:

我可以向您保证,我不会以上述任何一种方式关闭手柄。调用返回后调用 Close。该调用使用中止的 TryCatch 包装。 另外,这是一个 IO 异常,与常规通信错误不同。

以上是关于WCF 命名管道 IO 异常 - 管道已结束。 (109, 0x6d)的主要内容,如果未能解决你的问题,请参考以下文章

WCF NamedPipe CommunicationException - “管道已结束。 (109,0x6d)。“

WCF 命名管道在 WinApp 中超时,但在 ConsoleApp 中没有?

WCF 命名管道最小示例

未找到 WCF 命名管道端点

带有命名管道的 WCF:如何允许并行调用?

WCF 服务命名管道故障