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

    }
}
Community
  • 1
  • 1
dcp
  • 54,410
  • 22
  • 144
  • 164
  • do you have a virus scanner / firewall / security suite installed on that machine? – CaptainPlanet Jan 19 '11 at 19:32
  • @CaptainPlanet - Yes, but even after deinstalling them it's still slow. I tried with no virus scanner installed, and windows firewall turned off. Thanks for the thought though. – dcp Jan 19 '11 at 19:42
  • Can you show us the service **config**, especially the security settings?? The fact it wants to contact a domain would indicate that either you're using a binding that defaults to Windows credentials that the ServiceHost wants to establish a link to a Windows domain to check user credentials, or you have a custom authentication mechanism in place trying to contact an Active Directory domain. – marc_s Jan 19 '11 at 19:59
  • @marc_s - See my latest edit. Note that there's no special security configuration in the app.config, however, note that SessionMode is required on the service contract interface definition. If I take SessionMode out, then I don't have the problem. But I still don't understand why it still thinks it needs to contact a domain. – dcp Jan 19 '11 at 20:41
  • @marc_s - What I posted was my entire app.config. As I said, there's no special security configuration in the app.config. If there's something I'm not understanding, or you need to see something else, please let me know. In a normal WCF app, I'm aware that I would have the services node and the endpoint configuration for the clients, etc, but in this little test app, I don't have any of that. – dcp Jan 19 '11 at 20:50
  • @marc_s - No, 3.5 in this case. – dcp Jan 19 '11 at 21:34

4 Answers4

4

Okay, my suspicion is the fact you're using a binding (WsHttpBinding) which defaults to authenticating its callers using Windows credentials unless you specifically tell it not to.

In your service hosting code, you're just instantiating a default WsHttpBinding instance - no settings in config or code to change the default security behavior, in that case.

Just for testing purposes: try to change your service hosting code to:

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

This will effectively cancel out all security settings, e.g. the ServiceHost should no longer even attempt to find the Windows domain to authenticate callers against.

Does that change any of your observations?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • No, that causes an exception "System.InvalidOperationException Contract requires Session, but Binding 'WSHttpBinding' doesn't support it or isn't configured properly to support it". But thank you for the suggestion, I'm grateful for it. I emailed you the zip file containing the entire program and solution file if you want to play around with it (hope that was ok :)). – dcp Jan 20 '11 at 01:01
  • @dcp: try this: use the `SecurityMode.None` in your constructor, and remove the `SessionMode.Required` from your service contract - your `ServiceHost` will now open within the blink of en eye (less than 1 second). Setting up session mode and all that stuff carries overhead.... so why would you need SessionMode.Required in a service like this?? – marc_s Jan 20 '11 at 05:39
  • Yes, I was already aware that removing the SessionMode.Required eliminates the overhead and the service opens quickly, because I had tried that a while back. But the question is, why when SessionMode.Required is present does it take 7 seconds for the machine to figure out it's not part of a domain? As for why SessionMode.Required is needed, it really isn't in this short example, but in my real WCF services, we use a lot of transactions, etc. and sometimes sessions are required between endpoints. Anyway, thanks again for your suggestions. – dcp Jan 20 '11 at 13:39
3

It turns out that if I disable netbios on my network connections, I don't get the delays on the ServiceHost.Open calls. I am not sure why, but this seemed to fix the problem.

What's weird is that when I did a clean install of XP, I didn't have the delays even with the Netbios enabled, so I have no idea why it happens with my existing installation (I did the clean install on this same machine, and then restored my backup from an image to run these tests).

dcp
  • 54,410
  • 22
  • 144
  • 164
0

It seems I had the same Problem. Long Duration of Open call caused by an exception. I googled for configuration of security Settings for Wcf Service. Found the following solution which worked for me:

Under <wsHttpBinding> element in the Web.config file place the following entry:

<security mode="None" />

The Service Reference in the Client must be updated!

pb2q
  • 58,613
  • 19
  • 146
  • 147
Juergen
  • 1
  • 1
0

Also try stopping the Remote Access Auto Connection Manager service. For me, the issue came down to Dns.GetHostEntry(String.Empty) and this post http://social.msdn.microsoft.com/Forums/en/vbgeneral/thread/493d1b65-9ace-41de-b269-f178d27a8a1b