【问题标题】:How can I diagnose the cause of a WCF Service Timeout?如何诊断 WCF 服务超时的原因?
【发布时间】:2013-12-20 19:05:10
【问题描述】:

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

  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

代码 sn-ps 和异常数据:

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)     

【问题讨论】:

标签: c# .net wcf service netnamedpipebinding


【解决方案1】:

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

查看 WCF 服务启动配置

评估错误跟踪活动

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

【讨论】:

    猜你喜欢
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 2020-04-05
    相关资源
    最近更新 更多