使用NamedPipesBinding的WCF服务获取PipeException(管道正在关闭)

时间:2012-08-13 13:17:36

标签: c# .net wcf wcf-binding wcf-client

我只是在学习WCF,尝试不同的东西。

我已经设置了以下服务:

[ServiceBehavior(IncludeExceptionDetailInFaults = true , 
    InstanceContextMode = InstanceContextMode.Single)]
    public class TestService : ITestService
    {
        // This operation is defined as OneWay.
        public void Throws()
        {
            throw new ArgumentException();
        }
    }

我从我的客户那里使用它:

var baseAddress = new Uri("net.pipe://localhost/hello");

// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(TestService), baseAddress))
{
    var netBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
    host.AddServiceEndpoint(typeof(ITestService), netBinding, baseAddress);
    host.Open();

    Console.WriteLine("The service is ready at {0}", baseAddress);

    // Create client channel.
    var channel = ChannelFactory<ITestService>.CreateChannel(netBinding, new EndpointAddress(baseAddress));

    ((ICommunicationObject)channel).Open();

    try
    {
        foreach (var i in Enumerable.Range(0, 5000))
        {
            // channel dies after a few attempts.
            channel.Throws();
        }
    }

方法投掷被定义为IsOneWay = true,这意味着它不会将任何消息传播回客户端(包括错误)。

在循环中运行时,通信对象在一些运行后出现故障。 我无法弄清楚原因。

例外情况:

  

System.ServiceModel.CommunicationException:写入时出错   到管道:管道正在关闭。 (232,0xe8)。 ---&GT;   System.IO.PipeException:写入管道时出错:The   管道正在关闭。 (232,0xe8)。在   System.ServiceModel.Channels.PipeConnection.StartSyncWrite(字节[]   缓冲区,Int32偏移量,Int32大小,对象&amp;持有人)   System.ServiceModel.Channels.PipeConnection.Write(Byte [] buffer,Int32   offset,Int32 size,Boolean immediate,TimeSpan timeout,BufferManager   bufferManage r)---内部异常堆栈跟踪结束---

请注意,如果我将Throws方法的主体更改为其他内容,例如Console.WriteLine,则一切正常。

编辑:我已将示例项目上传到我的SkyDrive:http://sdrv.ms/NumUbR

如果有人想在本地编译它并查看它是否表现相同。

1 个答案:

答案 0 :(得分:5)

您只是在某个时刻超出可用带宽。它可能是管道,但它也可能在WCF堆栈中...处理异常是昂贵的,并且你在尽可能紧的循环中做了5000个。从异常更改为不返回任何内容的WriteLine()可以解决问题,因为它可以显着减少所需的带宽/处理。 (我确实看到你提到了OneWay,但我认为它没有太大变化。即使没有返回异常,它仍然需要处理)。

尝试将InstanceContextMode更改为PerCall。这是“高容量”服务的标准设置。它将缓解一些的拥堵。

另外,为了解决这些意见,托管这样的服务很好。 ServiceHost将管理自己的线程。