Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WCF:ServiceClient+;处置_Wcf - Fatal编程技术网

WCF:ServiceClient+;处置

WCF:ServiceClient+;处置,wcf,Wcf,这就是为什么我们需要为ServiceClient实现我们自己的包装器类的原因(如果我错了,请纠正我): 捕获异常的目的 在Dispose()方法中 .Close()可以抛出 “通信异常”或 “TimeoutException”-并防止 把你吊起来的那个人抓住了 使用.Abort()有两个例外 将更改服务器的状态 通信对象已关闭 立即这不会产生任何影响 顺其自然 未处理,因为nessecary呼叫 这些方法已经制定出来了 因为我们在Dispose()部分 因此,抛出一个 当作业实际是 做它应该做的

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

捕获异常的目的 在Dispose()方法中 .Close()可以抛出 “通信异常”或 “TimeoutException”-并防止 把你吊起来的那个人抓住了 使用.Abort()有两个例外 将更改服务器的状态 通信对象已关闭 立即这不会产生任何影响 顺其自然 未处理,因为nessecary呼叫 这些方法已经制定出来了 因为我们在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
}
公共类ServiceClientWrapper:IDisposable { 公共TServiceType通道{get;private set;} 私有只读ChannelFactory\u ChannelFactory; 公共ServiceClientWrapper(字符串端点) { _channelFactory=新的channelFactory(端点); Channel=_channelFactory.CreateChannel(); ((IChannel)通道); } #IDisposable的区域实现 公共空间处置() { 尝试 { ((IChannel)通道).Close(); } 捕获(通信例外) { ((IChannel)通道).Abort(); } 捕获(TimeoutException例外) { ((IChannel)通道).Abort(); } 捕获(例外) { ((IChannel)通道).Abort(); 投掷; } } #端区 } 当您可以执行以下操作时:

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
}
公共类ServiceClientWrapper:IDisposable { 公共TServiceType通道{get;private set;} 私有只读ChannelFactory\u ChannelFactory; 公共ServiceClientWrapper(字符串端点) { _channelFactory=新的channelFactory(端点); Channel=_channelFactory.CreateChannel(); ((IChannel)通道); } #IDisposable的区域实现 公共空间处置() { ((IChannel)通道).Abort(); } #端区 } 根据MSDN,
.Close()
.Abort()
都会将通信对象的状态更改为“已关闭”

关闭方法:

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

中止方法 立即按照规范中的规定进行同样的操作。它将无法完成任何仍在进行的操作…

关闭方法:

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

中止方法 立即按照规范中的规定进行同样的操作。它不会完成任何仍在进行的操作…

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

因此,如果可能的话,我们总是希望执行Close,但我们需要处理这样的情况,即情况非常糟糕,尝试执行Close将导致进一步的异常。

关键是Close()将优雅地关闭整个通信通道,包括通信协议要求的任何关闭握手,而Abort()是对客户端通道堆栈的粗暴破坏,没有尝试将关闭正确地传达给另一方。因此,中止可能会使服务器端资源仍被连接占用,而不会被进一步使用


因此,如果可能的话,我们总是希望执行Close,但我们需要处理这样的情况,即情况非常糟糕,尝试执行Close将导致进一步的异常。

啊,我明白了。我的想法是,为什么要为serviceClient实现自己的包装器类是有效的吗?还是只是一堆废话?@ebb:我不会那么粗鲁地说后者……但作为一个理由,它有点混乱,我们应该说:-)。人们编写包装器的主要原因是,消费IDisposable对象的标准模式(带有
using
块)在遇到异常时会给WCF客户端带来错误和不直观的行为,因为using块的右大括号}将在
Close()
无法成功的情况下抛出并隐藏原始的因果异常。。。。因此,人们将
Close()
包装在try/catch块中,并使用
Abort()
处理
CommunicationException
TimeoutException
,因为没有理由不处理异常,因为这会导致应用程序停止,既然我们已经从服务中调用了nessecary方法并得到了返回的值,那么就没有必要让应用程序停止——类似这样的事情?啊,我明白了。关于为什么要为serviceClient实现自己的包装器类,我的想法是正确的?还是只是一堆废话?@ebb:我不会那么粗鲁地说后者。。。但作为一个理由,它有点混乱,我们可以说:-)。人们编写包装器的主要原因是,使用
using
块消费IDisposable对象的标准模式在遇到异常时为WCF客户端提供了错误和不直观的行为,因为