【问题标题】:WCF how can I avoid faulted channels if they are closed by server due to inactivity如果由于不活动而被服务器关闭,WCF如何避免故障通道
【发布时间】:2011-12-24 12:11:35
【问题描述】:

我的服务主机配置为 10 分钟后关闭连接

<wsHttpBinding>
    <binding receiveTimeout="00:10:00">
</wsHttpBinding>

在我的客户端代码中,在使用服务之前,它已经过验证。如果它处于关闭/故障状态,它将创建一个新的。

    public static T ValidateService<T>(ref T service) where T : class
    {
        if (service is IClientChannel)
        {
            IClientChannel channel = service as IClientChannel;
            CommunicationState state = channel.State;
            if (state == CommunicationState.Faulted || state == CommunicationState.Closed)
            {
                // thread safe logic to create new service 
            }
        }
    }

问题是当通道在服务器端关闭时,channel.State 仍将返回打开状态。在我进行远程调用后,由于receiveTimeout,我得到了错误异常。

有没有办法让客户端不活动超时?类似于服务器上的receiveTimeout="00:10:00",但少了几秒钟,所以如果不使用我可以很好地关闭客户端的频道,如果需要,我的ValidateService&lt;T&gt; 逻辑将创建一个新频道。

出于性能原因,我不想为每个远程调用创建新通道,因为这些调用可能非常频繁。

我希望避免为我在通信中使用的每项服务设置心跳轮询器。

谢谢

【问题讨论】:

    标签: c# wcf timeout wcf-binding


    【解决方案1】:

    您无法避免处理FaultedClosed,因为某些网络问题或类似问题总是可能导致您必须创建新的Channel...

    编辑 - 根据评论:

    在生产中,我通常有一个客户端实现,它通过重新创建 Channel 并重试来处理某些异常...这会处理您所描述的情况以及其他几种情况,例如网络中断等。

    【讨论】:

    • 那么在客户端有没有更好的方法来处理receiveTimeout?如果上次使用的时间足够长,我正在考虑在客户端上有一个轮询器来做一些心跳或很好地关闭频道。类似于在客户端工作的 receiveTimeout。
    • @marek 在生产中,我通常有一个客户端实现,它通过重新创建通道并重试来处理某些异常......
    • 我希望有一种内置方法可以从客户端关闭未使用的通道,而不是最终导致客户端出现故障通道。我确实了解故障通道可能由于许多其他原因而发生,但我很惊讶没有一种很好的方法可以很好地关闭客户端未使用的通道,类似于 receiveTimeout。
    • @marek 假设有一种方法可以做到这一点......那么结果将是 ChannelStateClosed... 你的代码会发生什么变化?在if 的绝对最佳情况下,您将删除Faulted...我认为这不会是生产质量,因为Faulted 由于其他原因仍然可能发生...
    • @marek 您可以做的是创建类似于“数据库连接池”的“客户端池”,然后每次您获得“客户端”时,“池”都会首先对其进行验证并删除/适当地重新创建它...当您将其返回到“池”时,“池”将再次检查特定的 State 并丢弃/重新创建它...
    猜你喜欢
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-05
    • 2011-01-01
    • 2020-11-02
    相关资源
    最近更新 更多