3

This is a similar question as this one: Win32Exception @ ServiceHost.Open() for WCF service.

I have a machine that is very slow on the ServiceHost.Open call below. It consistently takes 7 seconds or so to open the service, every time. This machine is my home box, and it is not part of a domain.

I can run the same code on another box (my work box) which is part of a domain and the service host opens in about 3-4 seconds on the first call, but if I run the program again the service host opens in about 1 second or less.

I have worked with MS support on this, and we generated trace logs and the part it's hanging in is where is goes out and tries to connect to a domain, even on the machine that isn't part of a domain. And it gets the "The specified domain either does not exist or could not be contacted." exception in the trace log, and that's where all the time is getting eaten up.

But what's really weird is that even on my work machine, if I'm not connected to a domain (like if I'm not on my work network and just running from home) I still don't get the delay.

I rebuilt my machine using Windows 7 64-bit, and the same behavior occurs (was running XP SP3, which I restored when Windows 7 didn't seem to fix the problem).

I just wondered if anyone had any ideas of what could cause this. By the way, if I disable "Client for microsoft networks", the time is like 4 seconds to open the ServiceHost, but that's still not as fast as this machine used to be able to open the service. Somehow, it thinks it's supposed to be part of a domain or something.

    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;
    }

Here is my app.config, but I don't have any special security configuration settings for the service in there, only some diagnostic settings to enable the WCF trace.

<?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>

Note also that my service definition has SessionMode required (see below). If I take the SessionMode requirement out, I don't get the delays.

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

4 回答 4

4

好的,我的怀疑是您使用的绑定 ( WsHttpBinding) 默认使用 Windows 凭据对其调用者进行身份验证,除非您明确告诉它不要这样做。

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

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

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

这将有效地取消所有安全设置,例如,ServiceHost甚至不应再尝试查找 Windows 域来验证调用者的身份。

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

于 2011-01-19T21:42:24.593 回答
3

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

奇怪的是,当我全新安装 XP 时,即使启用了 Netbios,我也没有延迟,所以我不知道为什么我现有的安装会发生这种情况(我在同一台机器上进行了全新安装,并且然后从图像恢复我的备份以运行这些测试)。

于 2011-01-22T00:48:45.150 回答
0

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

于 2011-02-14T10:42:17.307 回答
0

看来我有同样的问题。由异常引起的长时间打开调用。我搜索了 Wcf 服务的安全设置配置。找到以下对我有用的解决方案:

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

<security mode="None" />

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

于 2013-11-05T22:09:18.797 回答