我一直在客户端得到WCF服务处于故障状态.如何在不破坏WCF服务的情况下捕获WCF异常?

本文关键字:WCF 服务 情况下 异常 服务处 客户端 于故障 状态 故障 我一直在 | 更新日期: 2023-09-27 18:15:11

我有一个多个用户使用的WCF服务。当用户无法访问数据库时,我从数据库获得未经授权的异常。我不会在服务器端捕获异常并将其发送给客户端。

在客户端(asp.net网页)上,我看到异常-用户无法访问数据库,登录失败。这些都很好。但是…如果再次调用WCF服务,就会得到服务处于故障状态的异常。只有打开才能重新启动整个WCF服务。WCF服务作为windows服务托管。

捕获异常,在服务器端记录异常,在不中断服务的情况下将异常详细信息发送回客户端的最佳方法是什么?由于

我一直在客户端得到WCF服务处于故障状态.如何在不破坏WCF服务的情况下捕获WCF异常?

未处理的异常将导致通信通道故障。正如其他人指出的那样,一个有故障的通道必须通过调用Abort()来中止——它不能被关闭,也不能再次使用。

要解决问题的另一部分,即"捕获异常,在服务器端记录异常,在不中断服务的情况下将异常详细信息发送回客户端的最佳方法?",您需要使用FaultException类。

另外,你可以使用IErrorHandler接口来连接你的服务主机,以捕获任何未被捕获的异常(即,一个全局错误处理程序)。网上有很多关于如何做到这一点的例子-只需谷歌WCF IErrorHandler。

这里有几个:

使用IErrorHandler处理WCF异常

WCF可扩展性- IErrorHandler

您可以使用以下代码创建一个包装器类,它将正确处理WCF异常:

public class ServiceProxyHelper<TProxy, TChannel> : IDisposable
    where TProxy : ClientBase<TChannel>, new()
    where TChannel : class
{
    ///
    /// Private instance of the WCF service proxy.
    ///
    private TProxy _proxy;
    ///
    /// Gets the WCF service proxy wrapped by this instance.
    ///
    public TProxy Proxy
    {
        get
        {
            if (_proxy != null)
            {
                return _proxy;
            }
            else
            {
                throw new ObjectDisposedException("ServiceProxyHelper");
            }
        }
    }
    public TChannel Channel { get; private set; }
    ///
    /// Constructs an instance.
    ///
    public ServiceProxyHelper()
    {
        _proxy = new TProxy();
    }
    ///
    /// Disposes of this instance.
    ///
    public void Dispose()
    {
        try
        {
            if (_proxy != null)
            {
                if (_proxy.State != CommunicationState.Faulted)
                {
                    _proxy.Close();
                }
                else
                {
                    _proxy.Abort();
                }
            }
        }
        catch (CommunicationException)
        {
            _proxy.Abort();
        }
        catch (TimeoutException)
        {
            _proxy.Abort();
        }
        catch (Exception)
        {
            _proxy.Abort();
            throw;
        }
        finally
        {
            _proxy = null;
        }
    }
}

你可以这样调用一个服务:

using (ServiceProxyHelper<EmailServiceClient, EmailService> svc =
   new ServiceProxyHelper<EmailServiceClient, EmailService>())
{
   svc.Proxy.SendMail(fromAddress, fromName, toEmail, toName, message);
}

请参阅下面的链接,该链接讨论了WCF客户端应该如何捕获错误/异常以及c#中'using'语句可能遇到的潜在问题:

http://msdn.microsoft.com/en-us/library/aa355056.aspx

基本上,您需要在客户端代理上调用Abort()。这将立即将代理的状态设置为关闭。