2013-12-20 66 views
0

我正在創建一個C#windows服務,它使用一個NetNamedPipeBinding與C#程序進行通信。該服務工作如下。如何診斷WCF服務超時的原因?

  1. 用戶在服務上調用「運行」命令。
  2. 服務觸發一個運行數據庫查詢的線程。
  3. 用戶在服務上調用「GetStatus」(大約每秒一次)。

不幸的是,GetStatus經常超時。這些超時發生在運行服務的中途。即使在第2步中的線程運行完畢後,這些超時仍會繼續。 5到10分鐘後,GetStatus的呼叫停止超時。

如何診斷這些超時的原因?


事情我已經嘗試:

  1. 添加ServiceBehavior(UseSynchronizationContext = false)DataSenderService
  2. ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)添加到DataSenderService
  3. 將調試器附加到服務(在超時期間,從不輸入GetStatus調用)。
  4. 驗證在超時期間ServiceHost.State設置爲CommunicationState.Opened

代碼段和異常數據:

public partial class DataSenderService : ServiceBase 
{ 
    private ServiceHost _host; 
    protected override void OnStart(string[] args) 
    { 
     _host = new ServiceHost(typeof(DataSender), new Uri("net.pipe://localhost")); 
     NetNamedPipeBinding pipeBinding = new NetNamedPipeBinding(); 
     pipeBinding.Security.Mode=NetNamedPipeSecurityMode.None; 
     _host.AddServiceEndpoint(typeof(IDataSender), pipeBinding, "MyPipeXA"); 
     _host.Open(); 
    } 
    //More stuff... 
} 

-

public class DataSender : IDataSender 
{ 
    private static WorkerObject MyWorkerObject { get; set; } 
    public string GetStatus() 
    { 
     WorkerObject req = MyWorkerObject; 
     return req == null ? "NULL" : req.TaskState; 
    } 
    public void Run() 
    { 
     MyWorkerObject = new WorkerObject(); 
     //Start function uses delegate.BeginInvoke to 
     //execute a function which makes database queries. 
     MyWorkerObject.Start(); 
    } 
    //More Stuff... 
} 

-

//Client 
void Main() 
{ 
    var pipeBinding = new NetNamedPipeBinding(); 
    pipeBinding.MaxReceivedMessageSize = 5000000; 
    pipeBinding.ReaderQuotas.MaxArrayLength = 5000000; 
    pipeBinding.Security.Mode = NetNamedPipeSecurityMode.None; 
    var pipeFactory = new ChannelFactory<IDataSender>(pipeBinding,new EndpointAddress("net.pipe://localhost/MyPipeXA")); 
    IDataSender pipeProxy = pipeFactory.CreateChannel(); 
    pipeProxy.Run();   

    //We call this about once per second. 
    //Eventually it starts triggering timeouts 
    Console.WriteLine(pipeProxy.GetStatus()); 
} 

-

TimeoutException: 
    Message: The open operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout. 
    InnerException: TimeoutException 
     Message: The read from the pipe did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout. 
     StackTrace: 
      at System.ServiceModel.Channels.PipeConnection.WaitForSyncRead(TimeSpan timeout, Boolean traceExceptionsAsErrors) 
      at System.ServiceModel.Channels.PipeConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) 
      at System.ServiceModel.Channels.DelegatingConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout) 
      at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper) 
      at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper) 
      at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout) 
      at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout) 
    StackTrace: 
     Server stack trace: 
      at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout) 
      at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 
      at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout) 
      at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout) 
      at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout) 
      at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade) 
      at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) 
      at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation) 
      at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message) 
     Exception rethrown at [0]: 
      at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg) 
      at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)  
+1

你嘗試一個WCF跟蹤的HTTP://stackoverflow.com/questions/4271517/how-to-turn-on-wcf-tracing –

+0

謝謝。顯然,我並沒有關閉連接並最大化併發連接。 – Brian

回答