WCF慢速ServiceHost.Open()调用

时间:2011-01-19 19:10:50

标签: wcf servicehost

这是一个与此类似的问题:  Win32Exception @ ServiceHost.Open() for WCF service

我在下面的ServiceHost.Open调用中有一台非常慢的机器。每次打开服务一直需要7秒左右。这台机器是我的主机,它是域的一部分。

我可以在另一个框(我的工作框)上运行相同的代码,其中 是域的一部分,并且服务主机在第一次调用时大约3-4秒打开,但如果我运行程序再次服务主机在大约1秒或更短的时间内打开。

我已经与MS一起工作了,我们生成了跟踪日志,它所挂起的部分就是在哪里出去尝试连接到域,即使是在不属于域的机器上也是如此。它得到“指定的域名不存在或无法联系”。跟踪日志中的异常,这就是所有时间都被吃掉的地方。

但真正奇怪的是,即使在我的工作机器上,如果我没有连接到域(例如,如果我不在我的工作网络上,只是在家里跑),我仍然不< / strong>得到延迟。

我使用Windows 7 64位重建了我的机器,并且出现了相同的行为(正在运行XP SP3,当Windows 7似乎无法解决问题时我恢复了这一点。)

我只是想知道是否有人有任何可能导致这种情况的想法。顺便说一下,如果我禁用“微软网络客户端”,打开ServiceHost的时间就好于4秒,但这仍然不如此机器打开服务那么快。不知何故,它认为它应该是域名的一部分。

    static void RunServiceWithinEXE()
    {
        Uri baseAddress = new Uri("http://localhost:11111/Demo");
        ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress);

        try
        {
            // Add a service endpoint
            serviceHost.AddServiceEndpoint(
                typeof(ICalculator),
                new WSHttpBinding(),
                "CalculatorService");

            // Enable metadata exchange
            ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
            smb.HttpGetEnabled = true;
            serviceHost.Description.Behaviors.Add(smb);
            serviceHost.Opening += new EventHandler(serviceHost_Opening);
            serviceHost.Opened += new EventHandler(serviceHost_Opened);
            serviceHost.Open();
            Console.WriteLine("The service is ready.");

            // Close the ServiceHostBase to shutdown the service.
            serviceHost.Close();
        }
        catch (CommunicationException ce)
        {
            Console.WriteLine("An exception occured: {0}", ce.Message);
            serviceHost.Abort();
        }
    }

    static void serviceHost_Opened(object sender, EventArgs e)
    {
        TimeSpan timeToOpen = DateTime.Now - shOpening;
        Console.WriteLine("Time To Open: :" + timeToOpen.Seconds);
    }

    static void serviceHost_Opening(object sender, EventArgs e)
    {
        shOpening = DateTime.Now;
    }

这是我的app.config,但我没有任何特殊的安全配置设置,只有一些诊断设置可以启用WCF跟踪。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <diagnostics>
            <messageLogging maxMessagesToLog="30000"
                    logEntireMessage="true"
                    logMessagesAtServiceLevel="false"
                    logMalformedMessages="true"
                    logMessagesAtTransportLevel="true">
                <filters>
                    <clear/>
                </filters>
            </messageLogging>
        </diagnostics>
    </system.serviceModel>

    <system.diagnostics>
        <sources>
            <source name="System.ServiceModel" switchValue="Warning, ActivityTracing" propagateActivity="true" >
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
            <source name="System.ServiceModel.MessageLogging" switchValue="Warning">
                <listeners>
                    <add name="xml" />
                </listeners>
            </source>
        </sources>
        <sharedListeners>
            <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\Temp\Server.svclog" />
        </sharedListeners>
        <trace autoflush="true" indentsize="4">
            <listeners>
                <remove name="Default" />
                <add name="ScottsConsoleListener" type="System.Diagnostics.ConsoleTraceListener" />
                <add name="ScottsTextListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Temp\DebugLog.txt" />
            </listeners>
        </trace>
    </system.diagnostics>
</configuration>

另请注意,我的服务定义需要SessionMode(见下文)。如果我把SessionMode要求拿出来,我就不会有延迟。

using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Microsoft.ServiceModel.Samples
{
    // Define a service contract.
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode = SessionMode.Required)]
    public interface ICalculator
    {
        [OperationContract]
        double Add(double n1, double n2);

        [OperationContract]
        double Subtract(double n1, double n2);

        [OperationContract]
        double Multiply(double n1, double n2);

        [OperationContract]
        double Divide(double n1, double n2);

        [OperationContract]
        string PrintName(string firstName, string lastName);

        [OperationContract]
        Point MakePoint(double x, double y);

    }
}

4 个答案:

答案 0 :(得分:4)

好的,我怀疑你正在使用绑定(WsHttpBinding),默认情况下使用Windows凭据对其调用者进行身份验证,除非你明确告诉它不要。

在您的服务托管代码中,您只是实例化一个默认的WsHttpBinding实例 - 在这种情况下,配置或代码中没有设置来更改默认的安全行为。

仅用于测试目的:尝试将您的服务托管代码更改为:

 // Add a service endpoint
 serviceHost.AddServiceEndpoint(
            typeof(ICalculator),
            new WSHttpBinding(SecurityMode.None),  // pass in SecurityMode.None
            "CalculatorService");

这将有效地取消所有安全设置,例如ServiceHost应该不再尝试找到Windows域来对来电进行身份验证。

这会改变你的任何观察结果吗?

答案 1 :(得分:3)

事实证明,如果我在网络连接上禁用netbios,我就不会收到ServiceHost.Open调用的延迟。我不知道为什么,但这似乎解决了这个问题。

奇怪的是,当我干净安装XP时,即使启用了Netbios,我也没有延迟,所以我不知道为什么它会在我现有的安装中发生(我在同样的地方进行了干净安装)机器,然后从图像恢复我的备份以运行这些测试)。

答案 2 :(得分:0)

还尝试停止远程访问自动连接管理器服务。对我来说,问题归结为Dns.GetHostEntry(String.Empty)和这篇文章http://social.msdn.microsoft.com/Forums/en/vbgeneral/thread/493d1b65-9ace-41de-b269-f178d27a8a1b

答案 3 :(得分:0)

我似乎遇到了同样的问题。由异常引起的长时间公开呼叫。我用Google搜索配置Wcf服务的安全设置。找到了适合我的以下解决方案:

Web.config 文件的<wsHttpBinding>元素下放置以下条目:

<security mode="None" />

必须更新客户端中的服务参考!