【问题标题】:TimeoutException in WCF after multiple calls多次调用后 WCF 中的 TimeoutException
【发布时间】:2012-05-12 08:29:30
【问题描述】:

也许我执行 WCF 不正确,但在多次调用后使用 NetNamedPipedBindings 时似乎遇到了 WCF 异常。

这是我正在做的高级别的事情。基本上,我正在处理一个 out of proc exe 并使用 WCF 命名管道来回通信。我通过这个属性让我的主机保持打开状态:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
    ConcurrencyMode = ConcurrencyMode.Multiple)]

然后,在我的客户端中,我创建了一个 static DuplexChannelFactory,我将其实例化一次,然后根据需要通过以下方式使用:

channelFactory.CreateChannel().MakeCall();

我添加了一个 Ping 方法只是为了确保主机正常工作(因为主机会发回我们不想在不知道的情况下错过的事件)。此 Ping 方法每 5 秒运行一次,并且只返回一个 true。然而,在运行了几分钟后,我得到了一个TimeoutException。这是我的异常跟踪:

服务器堆栈跟踪:在 System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(时间跨度 超时)在 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)在 System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan 超时)
在 System.ServiceModel.Channels.CommunicationObject.Open(时间跨度 超时)在 System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel 通道,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(时间跨度 超时,CallOnceManager 级联)在 System.ServiceModel.Channels.ServiceChannel.EnsureOpened(时间跨度 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串 action, Boolean oneway, ProxyOperationRuntime 操作, Object[] ins, Object[] 出局,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串动作, Boolean oneway, ProxyOperationRuntime 操作, Object[] ins, 对象 [] 出局)在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime 操作)在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 留言)

我打开 JustDecompile 发现这个错误很可能发生在这里:

connection = this.connectionPoolHelper.EstablishConnection(timeout)

但是,我看不出有什么原因会在之前进行几次 ping 操作后超时?我需要设置什么设置才能使这个无限和/或我是否有另一种方法可以从客户端或服务器端实现这个 WCF 事件服务器(它也用于按需处理)?

更新

在我开始看到呼叫尝试并且没有返回之前,我进行了大约 6 次 ping。

【问题讨论】:

  • 我看不出为什么这会在之前工作几分钟后超时? - 这实际上很有意义并将其标记为资源泄漏。您没有关闭/处置某些东西。
  • @HenkHolterman 好的,但是服务器或客户端上的东西是什么?我不应该多次调用 CreateChannel 吗?也许 CreateChannel 并一遍又一遍地使用它?我的猜测是它在客户端的某个地方,因为我可以保持服务器正常运行,杀死客户端,它会在客户端重新启动时工作一点。
  • 嗯,6 次 ping 是半分钟,而不是几分钟。
  • 我对双工通道不太熟悉,但我会说每次使用后保持打开或丢弃。池的存在表明后者具有using(){} 模式。
  • @HenkHolterman 我会试一试,并会更新我的问题。在我得到第一个异常之前还有几分钟,多线程计时器让我失望了。

标签: c# .net wcf timeout duplex-channel


【解决方案1】:

问题是你不能一遍又一遍地调用CreateChannel。没有 dispose 方法,因为这只是我的 WCF 接口的代理。所以,我只是通过存储对代理的引用并在需要重新实例化主机时重新创建它来解决这个问题。

您会认为会有一些关于此的文档。当博客写的时候他们确实多次调用 CreateChannel 时,这尤其没有帮助。

更新:

Here is what I found as to how this should be solved...although it did not work for me.., but seems to for others

在链接失效的情况下截取代码:

您必须使用转换为 IClientChannel 的 using,然后在 using 中重置您的引用。该通道将正常关闭,但您的参考将保持打开状态。注意演员表

using (IClientChannel client = (IClientChannel)channelFactory.CreateChannel())
{
    var proxy = (IMyInterface)client;
}

【讨论】:

  • 您可以将频道引用转换为 IClientChannel,或直接转换为 IDisposable。然后使用 using。
  • 我将不得不尝试,但如果我这样做,我可以使用我的类方法吗?
【解决方案2】:

您应该使用来自 sysinternals 的PipeList 来查看您是否继续不必要地创建新管道。它们将显示为 GUID。见MSDN blogs for further reference on WCF named pipe naming conventions

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多