我正在开发一个应用程序,该应用程序用于在同一台机器上的 WCF 服务 (ServiceA) 和 Windows 服务 (ServiceB) NetNamedPipeBinding
之间进行通信。WSDualHttpBinding
我在 ServiceA 中有一个代理类,它创建一个 ChannelFactory,然后是 NetNamedPipe Channel。然后缓存此通道并用于与 ServiceB 的所有通信。
基本上,每当我需要使用该NetNamedPipeBinding
服务拨打电话时,我都会得到ChannelProxy
这样的信息:
private ManagerProxy _managerProxy;
private ManagerProxy managerProxy
{
get
{
lock (lockObj)
{
if (_managerProxy == null)
{
LogWarning("managerProxy", "_managerProxy == null. Creating proxy.");
_managerProxy = new ManagerProxy();
}
else if (_managerProxy != null && (_managerProxy.State == CommunicationState.Closed || _managerProxy.State == CommunicationState.Closing || _managerProxy.State == CommunicationState.Faulted))
{
LogError("managerProxy", string.Format("_managerProxy.State == {0}. Attempting to renew proxy.", _managerProxy.State.ToString()), null, (int)ErrorReference.ProxyFaultedOrClosed);
try
{
_managerProxy.Close();
}
catch (Exception ex)
{
//Log exception;
}
_managerProxy = null;
_managerProxy = new ManagerProxy();
}
EventLog.WriteEntry("managerProxy", string.Format("ManagerProxy's State == {0}", _managerProxy.State), EventLogEntryType.Information);
}
return _managerProxy;
}
}
现在,99% 的时间,一切正常,但偶尔,我会在日志中看到最后一行 - ManagerProxy's State == Opened
。在此检查之后,我立即尝试使用代理调用方法,但出现以下错误:
Action on the channel failed.
System.ServiceModel.CommunicationException: There was an error writing to the pipe: The pipe is being closed. (232, 0xe8).
---> System.IO.IOException: The write operation failed, see inner exception.
---> System.ServiceModel.CommunicationException: There was an error writing to the pipe: The pipe is being closed. (232, 0xe8).
---> System.IO.PipeException: There was an error writing to the pipe: The pipe is being closed. (232, 0xe8).
at System.ServiceModel.Channels.PipeConnection.StartSyncWrite(Byte[] buffer, Int32 offset, Int32 size, Object& holder)
at System.ServiceModel.Channels.PipeConnection.WriteHelper(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout, Object& holder)
--- End of inner exception stack trace ---
at System.ServiceModel.Channels.PipeConnection.WriteHelper(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout, Object& holder)
at System.ServiceModel.Channels.PipeConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
at System.ServiceModel.Channels.BufferedConnection.WriteNow(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, BufferManager bufferManager)
at System.ServiceModel.Channels.BufferedConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
at System.ServiceModel.Channels.ConnectionStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.NegotiateStream.StartWriting(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.NegotiateStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
--- End of inner exception stack trace ---
at System.Net.Security.NegotiateStream.ProcessWrite(Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.NegotiateStream.Write(Byte[] buffer, Int32 offset, Int32 count)
at System.ServiceModel.Channels.StreamConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.StreamConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout)
at System.ServiceModel.Channels.StreamConnection.Write(Byte[] buffer, Int32 offset, Int32 size, Boolean immediate, TimeSpan timeout, BufferManager bufferManager)
at System.ServiceModel.Channels.FramingDuplexSessionChannel.OnSendCore(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.TransportDuplexSessionChannel.OnSend(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.OutputChannel.Send(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.DuplexChannelBinder.Request(Message message, TimeSpan timeout)
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)
at [My code] [line]
为什么我得到State == Opened
并立即无法写入管道?
我是否应该对保留 ProxyChannel 的方式进行一些架构更改?