6

我只是在学习 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();
        }
    }

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

在循环中运行时,通信对象在运行一些之后会出现故障。我无法弄清楚造成这种情况的原因。

异常详情:

System.ServiceModel.CommunicationException:写入管道时出错:管道正在关闭。(232, 0xe8)。---> System.IO.PipeException:写入管道时出错:管道正在关闭。(232, 0xe8)。在 System.ServiceModel.Channels.PipeConnection.StartSyncWrite(Byte[] buffer, Int32 offset, Int32 size, Object& holder) at System.ServiceModel.Channels.PipeConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan 超时,BufferManager bufferManager r) --- 内部异常堆栈跟踪结束 ---

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

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

如果有人想在本地编译它并查看它的行为是否相同。

4

1 回答 1

5

You are simply exceeding the available bandwidth at some point. It’s likely the pipe, but it might also be in the WCF stack… processing exceptions is expensive and you are doing 5000 of them in as tight a loop as possible. Changing from an exception to a WriteLine() that returns nothing fixes the problem because it dramatically reduces the required bandwidth/processing. (I do see you mentioned OneWay, but I don't think it changes much. Even if the exception isn't returned, it still has to be processed).

Try changing InstanceContextMode to PerCall. That's the standard setting for “high volume” services. It will relieve some of the congestion.

Also to address the comments, hosting the service like this is fine. The ServiceHost will manage its own threads.

于 2012-08-13T21:19:01.913 回答