如何防止通道异常使WCF服务停止工作?

时间:2009-12-24 21:55:34

标签: .net wcf exception timeout channel

我使用netNamedPipeBinding创建了一个WCF单例服务。发生通道异常时,会使通道处于故障状态,并且所有后续操作都会引发异常。我怎么能阻止这个?我希望TimeoutException或任何其他常见异常只能使一个操作失败,而不是让服务无响应。

2 个答案:

答案 0 :(得分:8)

您需要将服务器端的异常包装到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

答案 1 :(得分: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);
});