【问题标题】:WCF: ServiceClient + DisposeWCF:服务客户端 + 处置
【发布时间】:2011-07-01 13:37:21
【问题描述】:

这就是我理解为什么我们需要为 serviceClients 实现自己的包装类的原因(如果我错了,请纠正我):

捕获异常的目的 在 Dispose() 方法中是 .Close() 可能会抛出一个 “通讯异常”或 “TimeoutException” - 并防止 挂你的连接抓住那些 使用 .Abort() 的两个例外 将改变状态 通讯对象关闭 立即。 - 它不会使任何 让例外成为意义 未处理,因为必要的电话 方法已经制定 因为我们在 Dispose() 部分,并且 因此,抛出一个很奇怪 当工作实际上是异常时 应该做的。

但为什么要这样做:

public class ServiceClientWrapper<TServiceType> : IDisposable
{
    public TServiceType Channel { get; private set; }
    private readonly ChannelFactory<TServiceType> _channelFactory;

    public ServiceClientWrapper(string endpoint)
    {
        _channelFactory = new ChannelFactory<TServiceType>(endpoint);
        Channel = _channelFactory.CreateChannel();
        ((IChannel)Channel).Open();
    }

    #region Implementation of IDisposable

    public void Dispose()
    {
        try
        {
            ((IChannel)Channel).Close();
        }
        catch (CommunicationException ex)
        {
            ((IChannel)Channel).Abort();
        }
        catch (TimeoutException ex)
        {
            ((IChannel)Channel).Abort();
        }
        catch (Exception)
        {
            ((IChannel)Channel).Abort();
            throw;
        }
    }

    #endregion
}

什么时候可以做:

public class ServiceClientWrapper<TServiceType> : IDisposable
{
    public TServiceType Channel { get; private set; }
    private readonly ChannelFactory<TServiceType> _channelFactory;

    public ServiceClientWrapper(string endpoint)
    {
        _channelFactory = new ChannelFactory<TServiceType>(endpoint);
        Channel = _channelFactory.CreateChannel();
        ((IChannel)Channel).Open();
    }

    #region Implementation of IDisposable

    public void Dispose()
    {
        ((IChannel)Channel).Abort();
    }

    #endregion
}

根据 MSDN,.Close().Abort() 都会将通信对象的状态更改为“关闭”?

【问题讨论】:

    标签: wcf


    【解决方案1】:

    关闭方法:

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

    此方法使 CommunicationObject 从任何状态(关闭状态除外)优雅地转换为关闭状态。 Close 方法允许在返回之前完成任何未完成的工作。例如,完成所有缓冲消息的发送。

    中止方法 立即不雅地或按照规格中的说明做同样的事情。它不会完成任何仍在进行的事情......

    【讨论】:

      【解决方案2】:

      关键是 Close() 将旨在优雅地关闭整个通信通道,包括通信协议所需的任何关闭握手,而 Abort() 是对客户端通道堆栈的粗鲁和残酷的拆除,没有尝试将关闭正确地传达给另一方。因此,中止可能会使服务器端资源仍被绑定在不会被进一步使用的连接上。

      因此,如果可能,我们总是希望执行 Close,但我们需要处理事情严重到试图执行 Close 会导致进一步异常的情况。

      【讨论】:

      • 啊,我明白了。我对为什么要为 serviceClient(s) 实现自己的包装类的想法是有效的?还是只是一堆废话?
      • @ebb:我不会这么粗鲁地说后者......但作为一个理由它有点困惑,我们应该说:-)。人们编写包装器的主要原因是因为使用 IDisposable 对象的标准模式(带有 using 块)在面对异常时为 WCF 客户端提供了不正确且不直观的行为,因为 using 块的右大括号 } 将抛出并隐藏Close() 无法成功的情况下的原始导致异常。
      • ... 因此人们将 Close() 包装在 try/catch 块中,并将使用 Abort() 处理 CommunicationExceptionTimeoutException,因为没有理由让异常不被处理,因为这将导致应用程序停止,并且由于我们已经从服务中调用了必要的方法并获得了返回的值,所以不需要让应用程序停止 - 类似的事情?
      猜你喜欢
      • 1970-01-01
      • 2010-09-22
      • 2010-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多