如何诊断WCF服务超时的原因?

时间:2013-12-20 19:05:10

标签: c# .net wcf service netnamedpipebinding

我正在创建一个C#windows服务,它使用NetNamedPipeBinding与C#程序通信。该服务的工作原理如下。

  1. 用户在服务上调用“运行”命令。
  2. 服务会触发一个运行数据库查询的线程。
  3. 用户在服务上调用“GetStatus”(大约每秒一次)。
  4. 不幸的是,GetStatus经常超时。这些超时发生在运行服务的中途。即使在步骤2中的线程完成运行后,这些超时仍会继续。 5到10分钟后,对GetStatus的调用停止超时。

    如何诊断这些超时的原因?


    我尝试过的事情:

    1. ServiceBehavior(UseSynchronizationContext = false)添加到DataSenderService
    2. ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)添加到DataSenderService
    3. 将调试程序附加到服务(在超时期间,永远不会输入GetStatus调用)。
    4. 确认在超时期间ServiceHost.State设置为CommunicationState.Opened

    5. 代码段和异常数据:

      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 个答案:

答案 0 :(得分:3)

您可能需要考虑启用WCF跟踪和日志记录,以便:

查看WCF服务启动配置

enter image description here

评估错误跟踪活动

enter image description here

以下链接提供了全面的概述:
http://msdn.microsoft.com/en-us/library/ms733025(v=vs.110).aspx