2011-01-19 51 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" /> 

在客戶服務引用必須更新!