【问题标题】:How to prevent that a channel exception make a WCF service stop working?如何防止通道异常使 WCF 服务停止工作?
【发布时间】:2010-12-29 21:55:30
【问题描述】:

我使用 netNamedPipeBinding 创建了一个 WCF 单例服务。当通道异常发生时,它使通道处于故障状态,所有后续操作都会抛出异常。我怎样才能防止这种情况?我希望 TimeoutException 或任何其他常见异常仅使一个操作失败,而不是使服务无响应。

【问题讨论】:

  • 您确定是服务渠道因错误而无响应吗?我一直在一个非常大的网站上使用单例服务,我从来没有遇到过你描述的问题。
  • 我收到的日志显示通道无法使用,因为它处于故障状态

标签: .net wcf exception timeout channel


【解决方案1】:

您需要将服务器端的异常包装到 FaultException 中。如果您控制线路的两端,并且两端都是 .NET,则只需将 .NET 异常包装到 FaultException<T> 中并将其发送回客户端即可。这样通道就可以保持可用。

有关更多信息,请参阅 MSDN 上的 Specifying and Handling Faults in Contracts and Services,以及查看此 article on CodeProject 和此博客文章 Why Use WCF FaultException 关于同一主题。

另外,为了让您的生活更轻松,请查看IErrorHandler interface,您可以在服务器端实现它以全局捕获异常并将它们转换为故障。还可以查看有关该主题的大量博客文章,例如 IErrorHandler: a generic Fault Converter 或许多其他(Bing 或 Google 等)。

为了让您的生活更轻松,您可以将 IErrorHandler 实现为一种行为,您可以在服务上打开或关闭它 - 在服务配置中或通过在服务上设置属性班级。互联网上有很多实现,我喜欢的一个在这里:Useful WCF Behavior: IErrorHandler

【讨论】:

  • 也找到了另一种解决方法,请看我的回答
  • 有趣的是,当我实施我的解决方案时,我的服务停止工作,所以我必须实施你的服务才能让它们恢复正常。
  • 我发现我的解决方案有问题,我们不应该处理 Channels,因为它们很棘手,请参阅 stackoverflow.com/questions/2008382/…
【解决方案2】:

还有另一种方法。您可以为每个请求实例化客户端代理,而不是为多个请求使用单个实例。这样,如果通道进入故障状态,无论如何都会被丢弃。

这有点棘手,因为你不应该释放一个频道,除了它是 IDisposable 之外。

它不会工作:

using(var channel = channelFactory.CreateChannel())
{
    return channel.ServiceMethod(parameter);
}

相反,您应该:

public static class Service<T>
{
    public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>("");

    public static TResult Use<TResult>(Func<T, TResult> func)
    {
        TResult output;
        var channel = (IClientChannel)_channelFactory.CreateChannel();
        bool success = false;
        try
        {
            output = func((T)proxy);
            channel.Close();
            success = true;
        }
        finally
        {
            if (!success)
            {
                proxy.Abort();
            }
        }
        return output;
    }
}

return Service<IService>.Use(channel =>
{
    return channel.ServiceMethod(parameter);
});

【讨论】:

  • 我猜这里有一个错误:channelproxy 是一回事。我认为您应该将proxy 替换为channel
猜你喜欢
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
相关资源
最近更新 更多