也许我实现 WCF 不正确,但在进行多次调用后,我在使用 NetNamedPipedBindings
时似乎遇到了 WCF 异常。
这是我正在做的事情的高水平。基本上,我正在处理一个进程外的exe,并使用WCF命名管道来回通信。我通过此属性使主机保持打开状态:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple)]
然后,在我的客户端中,我创建了一个实例化一次的static DuplexChannelFactory
,然后根据需要通过以下方式使用:
channelFactory.CreateChannel().MakeCall();
我添加了一个 Ping 方法只是为了确保主机正常工作(因为主机会发回我们不想在不知情的情况下错过的事件(。此 Ping 方法每 5 秒运行一次,并且仅返回 true。但是,在运行了几分钟后,我得到了一个TimeoutException
.这是我的异常跟踪:
服务器堆栈跟踪:在 System.ServiceModel.Channels.ClientFramemingDuplexSessionChannel.OnOpen(TimeSpan 超时(在 System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan 超时(在 System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout(
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan 超时(在 System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel 通道,时间跨度超时(在 System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade( at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout( at System.ServiceModel.Channels.ServiceChannel.Call(String action, 布尔单向, 代理操作运行时操作, 对象[] ins, 对象[] outs, TimeSpan timeout( at System.ServiceModel.Channels.ServiceChannel.Call(String action, 布尔单向, ProxyOperationRuntime operation, Object[] ins, 对象[] outs( at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage 方法调用,代理操作运行时操作( at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息(
我已经打开了 JustDecompile,看到此错误很可能发生在这里:
connection = this.connectionPoolHelper.EstablishConnection(timeout)
但是,我看不出任何理由为什么在之前工作了几次 ping 后会超时?我需要设置什么设置才能使其无限和/或是否有另一种方法可以从客户端或服务器端实现此 WCF 事件服务器(它也用于按需处理(?
更新
在我开始看到呼叫尝试并且没有返回之前,我进行了大约 6 次 ping。
问题是你不能一遍又一遍地调用CreateChannel
。没有释放方法,因为这只是我的 WCF 接口的代理。因此,我只是通过存储对代理的引用并在主机需要重新实例化时重新创建它来解决此问题。
你会认为会有某种关于此的文档。当有博客被写成多次调用CreateChannel时,它尤其无济于事。
更新:
这是我发现的关于如何解决这个问题的方法......虽然它对我不起作用..,但似乎对其他人有用
在链接死亡的情况下截取代码:
你必须使用强制转换为 IClientChannel 的 使用,然后在 using 中重置你的引用。通道将正确关闭,但您的引用将保持打开状态。注意演员表
using (IClientChannel client = (IClientChannel)channelFactory.CreateChannel())
{
var proxy = (IMyInterface)client;
}
你应该使用sysinternals的PipeList来查看你是否不必要地不断创建新管道。它们将显示为 GUID。有关 WCF 命名管道命名约定的进一步参考,请参阅 MSDN 博客。