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

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

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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的扩展方法代码:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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;
 
        }
 
    }
 
}

  利用该扩展方法,在本应调用Close()方法的地方,代替为CloseConnection()方法,就可以避免写冗长的catch代码。而使用 Lambda表达式的方式可以说是独辟蹊径,使用起来与using语法大致接近。实现方法是定义一个静态方法,并接受一个 ICommunicationObject对象与Action委托:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class Util
 
{
 
    public static void Using(T client, Action action)
 
        where T : ICommunicationObject
 
    {
 
        try
 
        {
 
            action(client);
 
            client.Close();
 
        }
 
        catch (CommunicationException)
 
        {
 
            client.Abort();
 
        }
 
        catch (TimeoutException)
 
        {
 
            client.Abort();
 
        }
 
        catch (Exception)
 
        {
 
            client.Abort();
 
            throw;
 
        }
 
    }
 
}

  使用时,可以将原本的客户端代码作为Action委托的Lambda表达式传递给Using方法中:

双击代码全选
1
2
3
4
5
6
7
8
9
Util.Using(new MyClient(), client =>
 
    {
 
        client.SomeWCFOperation();
 
        //其他代码;
 
    });

http://tech.ddvip.com/2009-03/1236930451111278.html

WCF中的Dispose(转)的更多相关文章

  1. 跟我一起学WCF(8)——WCF中Session、实例管理详解

    一.引言 由前面几篇博文我们知道,WCF是微软基于SOA建立的一套在分布式环境中各个相对独立的应用进行交流(Communication)的框架,它实现了最新的基于WS-*规范.按照SOA的原则,相对独 ...

  2. 游刃于MVC、WCF中的Autofac

    为了程序的健壮性.扩展性.可维护性,依赖抽象而不是具体实现类等等,于是我选择了Autofac依赖注入容器 就是这个工厂来降低耦合.之前买东西是自己去超市,现在呢 我需要什么东西,他们给送过来直接拿到了 ...

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

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  4. 在WCF中实现双工通信

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  5. WCF中,通过C#代码或App.config配置文件创建ServiceHost类

    C# static void Main(string[] args) { //创建宿主的基地址 Uri baseAddress = new Uri("http://localhost:808 ...

  6. WCF学习之旅—WCF中传统的异常处理(十六)

    WCF中的异常处理 在软件开发过程中,不可能没有异常的出现,所以在开发过程中,对不可预知的异常进行解决时,异常处理显得尤为重要.对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地 ...

  7. 在Wcf中应用ProtoBuf替代默认的序列化器

    Google的ProtoBuf序列化器性能的牛逼已经有目共睹了,可以把它应用到Socket通讯,队列,Wcf中,身为dotnet程序员一边期待着不久后Grpc对dotnet core的支持更期待着Wc ...

  8. ajax调用本地wcf中的post和get

    我们可以通过jQuery调用本地或者远程的wcf服务,本文讲解的是对本地wcf服务的post和get调用方式. post和get到底有什么区别呢?此处不作详述. 但是,post对请求的数据格式更为严格 ...

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

    本文将定义一个 WCF 终结点行为扩展,以在 WCF 中使用更高效的 BinaryFormatter 进行二进制序列化,并实现对是否使用传统二进制序列化功能的可配置. 介绍 实现步骤 使用方法 效果 ...

随机推荐

  1. vue-11-自定义指令

    用于对纯 DOM 元素进行底层操作. // 注册一个全局自定义指令 v-focus Vue.directive('focus', { // 当绑定元素插入到 DOM 中. inserted: func ...

  2. SmtpClient SSL 发送邮件异常排查

    上周使用 SmtpCliet 发送邮件测试,在服务端配置 SSL 465 / 993 情况 ,客户端使用 465 SSL 端口发送邮件异常,测试代码如下: System.Net.ServicePoin ...

  3. 深入margin

    1.外边距叠加 外边距叠加是指两个垂直外边距相遇时,这两个外边距会合并成一个外边距,就是二变一,关键是叠加后的外边距会取值两个外边距最大的那个: 例子如下:创建A.B两个盒子,A定义一个margin- ...

  4. Java集合(续)

    java学习笔记 --- 集合 1.定义:集合是一种容器,专门用来存储对象 数组和集合的区别?   A:长度区别  数组的长度固定    集合长度可变         B:内容不同  数组存储的是同一 ...

  5. 强化学习6-MC与TD的比较-实战

    # encoding:utf-8 import numpy as np import matplotlib.pylab as plt ''' 随机行走问题 0 - 1 - 2 - 3 - 4 - 5 ...

  6. 2018-2019-2 20175224 实验三《敏捷开发与XP实验》实验报告

    一.实验报告封面 课程:Java程序设计 班级:1752班 姓名:艾星言 学号:20175224 指导教师:娄嘉鹏 实验日期:2019年4月29日 实验时间:13:45 - 15:25 实验序号:24 ...

  7. zepto和jquery关于获取css样式的试用差别

    例如 获取 html标签的 字体大小, zepto中方法:$("html").css( "font-size" ); jquery中方法:$("htm ...

  8. installshield 功能传送错误

                                       出现这种问题,网上有几种解决方法: 1.原因:卸载不干净或者installshield本身安装的问题 解决方法:①卸载老程序.②删 ...

  9. php多进程和多线程的比较

    前言 最近在学习php多进程和多线程的编程.说实话,这两样在工作中几乎都没有用到,毕竟php并不以异步处理擅长,对于网络请求同步处理可以解决绝大多数问题.但是既然有这样的机制,也了解一下,对于以后接触 ...

  10. Delphi直接实现分享图片功能

    procedure TCustomCameraViewDoc.ShareTextClick(Sender: TObject); var FSharingService: IFMXShareSheetA ...