2011-01-19 47 views
3

这是因为这一个类似的问题: Win32Exception @ ServiceHost.Open() for WCF serviceWCF慢ServiceHost.Open()调用

我有一个机器,是下面的ServiceHost.Open通话非常缓慢。每次打开服务始终需要7秒左右的时间。这台机器是我的家用机箱,它是而不是域的一部分。

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

我已经与MS支持人员就此进行了合作,并且我们生成了跟踪日志,而且它挂在的部分是出去的地方,并尝试连接到域,即使是不属于域的计算机也是如此。它会得到“指定的域名不存在或无法联系。”跟踪日志中的异常,这就是所有时间都被吃掉的地方。

但是,真正奇怪的是,即使在我的工作机器上,如果我没有连接到域(如果我不在我的工作网络上,只是在家中运行),我仍然不要获取延时。

我使用的是Windows 7 64位重建我的机器,并出现相同的行为(正在运行XP SP3,当Windows 7似乎没有解决这个问题,我恢复)。

我只是想知道如果任何人有什么可能会导致此任何想法。顺便说一句,如果我禁用“Client for Microsoft网络”,时间就像打开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); 

    } 
} 
+0

您在该机器上安装了病毒扫描程序/防火墙/安全套件吗? – CaptainPlanet 2011-01-19 19:32:38

+0

@CaptainPlanet - 是的,但即使在删除它们之后,它仍然很慢。我尝试了没有安装病毒扫描程序,并关闭了Windows防火墙。谢谢你的想法。 – dcp 2011-01-19 19:42:30

+0

你能告诉我们服务**配置**,尤其是安全设置吗?它想要联系域名的事实表明,要么使用默认为Windows凭据的绑定,ServiceHost希望建立到Windows域的链接来检查用户凭据,或者您有一个自定义身份验证机制联系Active Directory域。 – 2011-01-19 19:59:56

回答

3

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

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

4

好了,我怀疑是您使用的是绑定(WsHttpBinding),默认为验证使用Windows凭据它的调用者,除非你明确告诉它不要的事实。

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

只是为了测试目的:试图改变自己的服务托管代码:

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

这将有效地消除所有安全设置,例如ServiceHost应该不再尝试找到Windows域来验证呼叫者。

这是否改变您的任何意见?

0

看来我有同样的问题。由于例外引起的公开呼叫的持续时间长。我搜索配置Wcf服务的安全设置。发现了以下解决方案,它为我工作:

<wsHttpBinding>元素在的Web.config文件发生以下条目:

<security mode="None" /> 

在客户服务引用必须更新!