Wcf服务net.tcp调用失败

时间:2015-02-20 19:57:06

标签: c# wcf net.tcp

我尝试设置一些测试以了解WCF服务的工作原理。我有类似于basicHttp,netTcp,netPipe绑定的代码,用这些绑定调用WCF服务。

using (_log = new StreamWriter(@"C:\TestRunnerLog.txt", true))
{
    var methodCallInformation = new MethodCallInformation { Method = NetPipeServiceCall, TotalTimeTakenForAllMethodCalls = new TimeSpan(), TotalNumberOfTimesMethodCalled = 0, TimesErrored = 0 };

    for (var i = 0; i < 25000; i++)
    {
        try
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            using(var channelFactory = new ChannelFactory<IChatHub>(new NetTcpBinding { Security = new NetTcpSecurity { Mode = SecurityMode.None } }, "net.tcp://localhost/test/test.svc"))
            {
                var channel = channelFactory.CreateChannel();
                await channel.GetPeople();
            }
            stopwatch.Stop();
            return stopwatch.Elapsed;

            methodCallInformation.TotalTimeTakenForAllMethodCalls += stopwatch.Elapsed;
        }
        catch (Exception e)
        {
            methodCallInformation.TimesErrored++;
        }

        methodCallInformation.TotalNumberOfTimesMethodCalled++;
    }

    await _log.WriteLineAsync(string.Format("net.tcp:\tTimesCalled:{0}\tTotalTime:{1}\tAverageTime:{2}\tErrors:{3}", methodCallInformation.TotalNumberOfTimesMethodCalled, methodCallInformation.TotalTimeTakenForAllMethodCalls, new TimeSpan(methodCallInformation.TotalTimeTakenForAllMethodCalls.Ticks / methodCallInformation.TotalNumberOfTimesMethodCalled), methodCallInformation.TimesErrored));
}

我对我得到的结果感到困惑。我在本地运行所有迭代,并使服务和客户端都在我的机器上本地运行。根据我的研究,netPipe应该是最快的,其次是netTcp然后是basicHttp。代码我随机化了这些调用,而不是每个循环只为所有迭代调用一个绑定,如上例所示。

----------------------------------------------------------------------------------------------
http:       TimesCalled:24981   TotalTime:00:00:46.0452454  AverageTime:00:00:00.0018432    Errors:0
net.tcp:    TimesCalled:25168   TotalTime:00:00:16.7776697  AverageTime:00:00:00.0006666    Errors:17593
net.pipe:   TimesCalled:24786   TotalTime:00:00:50.5698790  AverageTime:00:00:00.0020402    Errors:0

我试图弄清楚我在做什么错误地使用net.tcp来解决所有这些错误以及为什么net.pipe的时间似乎太慢了。

以下是我在服务上设置的绑定:

<bindings>
    <basicHttpBinding>
        <binding name="basicHttpDefaultBinding" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647">
            <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
            <security mode="None">
                <transport clientCredentialType="None" />
            </security>
        </binding>
    </basicHttpBinding>
    <netTcpBinding>
        <binding name="netTcpDefaultBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
            <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
            <security mode="None">
                <transport clientCredentialType="None" />
                <message clientCredentialType="None" />
            </security>
        </binding>
    </netTcpBinding>
    <netNamedPipeBinding>
        <binding name="netNamedPipeDefaultBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
            <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" maxDepth="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
            <security mode="None">
            </security>
        </binding>
    </netNamedPipeBinding>
</bindings>

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

你的NetTcp测试很可能完成得更快,因为它在~25,000次中抛出了大约17,000个异常。您或多或少只是测试应用程序抛出异常的速度。

在本地运行时,绑定之间的差异几乎难以察觉,环境因素可能足以扭曲您的结果。在网络上,结果可能不同,主要是由于消息编码(二进制文件与带有二进制文件的文本更有效)。这有希望回答你为什么命名管道与NetTcp相比“慢”的问题。

其次,要确定NetTcp失败的原因,您需要停止隐藏异常。

    catch (Exception e)
    {
        // you should also be reporting your exception somewhere here...
        methodCallInformation.TimesErrored++;   

    }

或者只是将Visual Studio设置为中断所有异常并以调试模式运行。根据我的经验,推测某些可能产生错误的原因通常不是解决问题的好方法。这是一种只有在没有其他可用选项时才应保留的方法。如果您提供例外详细信息,我们可能会提供更多信息。