0
我正在創建一個C#windows服務,它使用一個NetNamedPipeBinding
與C#程序進行通信。該服務工作如下。如何診斷WCF服務超時的原因?
- 用戶在服務上調用「運行」命令。
- 服務觸發一個運行數據庫查詢的線程。
- 用戶在服務上調用「GetStatus」(大約每秒一次)。
不幸的是,GetStatus經常超時。這些超時發生在運行服務的中途。即使在第2步中的線程運行完畢後,這些超時仍會繼續。 5到10分鐘後,GetStatus的呼叫停止超時。
如何診斷這些超時的原因?
事情我已經嘗試:
- 添加
ServiceBehavior(UseSynchronizationContext = false)
到DataSenderService
。 - 將
ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)
添加到DataSenderService
。 - 將調試器附加到服務(在超時期間,從不輸入
GetStatus
調用)。 - 驗證在超時期間
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)
你嘗試一個WCF跟蹤的HTTP://stackoverflow.com/questions/4271517/how-to-turn-on-wcf-tracing –
謝謝。顯然,我並沒有關閉連接並最大化併發連接。 – Brian