WCF中的Dispose

在我翻译的InfoQ新闻《WCF的问题和Using语句块》中提到了释放客户端资源(其中包括端口、通道) 和关闭连接的问题。新闻并没有很深入地讨论,所以我想再补充一些内容。

毫无疑问,在.NET Framework中,一个资源(尤其是非托管资源)通常都需要实现IDisposable接口。 一旦实现了该接口,我们就可以使用using语句来管理资源,这是最便捷的方式。但是,一旦在using语句 中抛出了异常,就可能不会正确完成资源的回收,尤其是连接,很可能会一直打开,既占用了通道和端口 ,还可能出现资源的浪费,从而影响系统的性能和稳定性。

微软推荐的最佳实践是抛弃using语句,转而利用 try/catch(/finally)语句。它要求在try语句中调 用Close()方法,而在catch中调用Abort()方法。在新闻中已经说明了Close()与Abort()方法的区别,即 后者可以强制地关闭客户端,包括关闭客户端连接,释放资源。由于Close()方法可能会抛出 CommunicationException和TimeoutException异常,通常的客户端代码应该是这样: var myClient = new MyClient();
try
{
    //其他代码
    myClient.Close();
}
catch (CommunicationException)
{
    myClient.Abort();
}
catch (TimeoutException)
{
    myClient.Abort();
}
catch (Exception)
{
    myClient.Abort();
    throw;
}

在最后增加对Exception异常的捕获很有必要,因为我们不知道Close()方法会否抛出某些不可预知的 异常,例如 OutOfMemoryException等。新闻中提到Steve Smith的方法其实就是对这段冗长代码的封装, 封装方式是采用扩展方法,扩展的类型为ICommunicationObject。这是因为所有的客户端对象都实现了 ICommunicationObject接口。以下是Steve Smith的扩展方法代码:

public static class Extensions
{
    public static void CloseConnection(this ICommunicationObject myServiceClient)
    {
        if (myServiceClient.State != CommunicationState.Opened)
        {
            return;
        }
        try
        {
            myServiceClient.Close();
        }
        catch (CommunicationException ex)
        {
            Debug.Print(ex.ToString());
            myServiceClient.Abort();
        }
        catch (TimeoutException ex)
        {
            Debug.Print(ex.ToString());
            myServiceClient.Abort();
        }
        catch (Exception ex)
        {
            Debug.Print(ex.ToString());
            myServiceClient.Abort();
            throw;
        }
    }
}

时间: 2024-09-15 11:37:10

WCF中的Dispose的相关文章

艾伟:WCF中通过Dispose有效实现重用

在我翻译的InfoQ新闻<WCF的问题和Using语句块>中提到了释放客户端资源(其中包括端口.通道)和关闭连接的问题.新闻并没有很深入地讨论,所以我想再补充一些内容. 毫无疑问,在.NET Framework中,一个资源(尤其是非托管资源)通常都需要实现IDisposable接口.一旦实现了该接口,我们就可以使用using语句来管理 资源,这是最便捷的方式.但是,一旦在using语句中抛出了异常,就可能不会正确完成资源的回收,尤其是连接,很可能会一直打开,既占用了通道和端口, 还可能出现资源

WCF中通过Dispose有效实现重用

本文将详细介绍释放客户端资源(其中包括端口.通道)和关闭连接的问题.毫无疑问,在.NET Framework中,一个资源(尤其是非托管资源)通常都需要实现IDisposable接口.一旦实现了该接口,我 们就可以使用using语句来管理资源,这是最便捷的方式.但是,一旦在using语句中抛出了异常,就可能 不会正确完成资源的回收,尤其是连接,很可能会一直打开,既占用了通道和端口,还可能出现资源的浪 费,从而影响系统的性能和稳定性. 微软推荐的最佳实践是抛弃using语句,转而利用 try/cat

我的WCF之旅(3):在WCF中实现双工通信

双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具有一些变体,比如典型的订阅-发布模式就可以看成是双工模式的一种表现形式.双工消息交换模式使服务端回调(Callback)客户端操作成为可能. 一.两种典型的双工MEP 1.请求过程中的回调 这是一种比较典型的双工消息交换模式的表现形式,客户端在进行服务调用的时候,附加上一个回调对象:服务在对处理该处

艾伟:[原创]谈谈WCF中的Data Contract(4):WCF Data Contract Versioning

软件工程是一门独特的工程艺术,需要解决的是不断改变的需求变化.而对于WCF,对于SOA,由于涉及的是对多个系统之间的交互问题,如何有效地解决不断改变的需求所带来的问题就显得更为重要:Service端版本的变化能否保持现有Consumer的正常调用,Consumer端的改变不至于影响对Service 的正常调用.对于Data Contract来说就是要解决这样的问题:Service端或者Client对Data Type的改变不会影响Service的正常调用. 在系统开发过程中,通过对Data Ty

在 WCF 中使用高效的 BinaryFormatter 序列化

本文将定义一个 WCF 终结点行为扩展,以在 WCF 中使用更高效的 BinaryFormatter 进行二进制序列化,并实现对是否使用传统二进制序列化功能的可配置. 介绍 实现步骤 使用方法 效果   介绍 在 OEA 框架中,是使用 WCF 作为数据传输框架.但是使用 WCF 内部的二进制序列化,序列化后的数据大小,要比使用传统的 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter 类进行序列化后的数据大小要大得多.作

WCF技术剖析之十一:异步操作在WCF中的应用(下篇)

说完了客户端的异步服务调用(参阅WCF技术剖析之十一:异步操作在WCF中的应用(上篇)),我们在来谈谈服务端如何通过异步的方式为服务提供实现.在定义服务契约的时候,相信大家已经注意到了OperationContractAttribute特性具有一个bool类型的AsynPattern.该属性可以将一个服务操作定义成异步实现模式,接下来的内容主要是着眼于介绍异步操作的定义和实现原理. 一.异步操作的定义和实现原理 实现WCF异步服务操作模式在编程上具有一些限制:异步服务操作是通过两个配对的方法实现

WCF技术剖析之十一:异步操作在WCF中的应用(上篇)

按照操作执行所需的资源类型,我们可以将操作分为CPU绑定型(CPU Bound)操作和I/O绑定型(I/O Bound)操作.对于前者,操作的执行主要利用CPU进行密集的计算,而对于后者,大部分的操作处理时间花在I/O操作处理,比如访问数据库.文件系统.网络资源等.对于I/O绑定型操作,我们可以充分利用多线程的机制,让多个操作在自己的线程并发执行,从而提高系统性能和响应能力.服务调用就是典型的I/O绑定型操作,所以多线程在服务调用中具有广泛的应用.在本篇文章中,我们专门来讨论多线程或者是异步操作

WCF中的REST架构二 (支持AJAX的WCF服务

我在昨天的文章WCF中的REST架构一(REST 概述)谈了REST的基本概要,并提出了从HI REST (高REST)到 LO REST (低REST) 的RESTFULness(REST度)的概念.在今天的文章中,我将详细介绍大家可能最为熟悉的REST风格的WCF 服务:支持AJAX的服务.此类服务应属于LO REST的范畴.现在很多人直觉地将"好"等同于"高大全",因而低估了这种LO REST实现的价值.本篇将告诉你这决非事实,支持AJAX的WCF服务是足够强

谈谈WCF中的Data Contract(3)

谈谈WCF中的Data Contract(3):WCF Data Contract对Collection & Dictionary的支持 在本篇文章上一部分Order Processing的例子中,我们看到原本已Collection形式定义的DetailList属性(public IList<TDetail> DetailList),在Data Contract中却以Array的方式体现(public OrderDetail[] DetailList).我们现在就来详细地讨论一下基于C