WCF IDisposable接口应用功能详解

开发 开发工具
WCF IDisposable接口在实际使用中往往都会进行操作。我们今天将会在这篇文章中为大家详细介绍一下有关这方面的知识。

WCF是由微软公司开发的一款功能强大的.NET Framework 3.5的重要组成部件,主要作用于通信方面,在.NET Framework中,一个资源(尤其是非托管资源)通常都需要实现WCF IDisposable接口。一旦实现了该接口,我们就可以使用using语句来管理资源,这是最便捷的方式。但是,一旦在using语句中抛出了异常,就可能不会正确完成资源的回收,尤其是连接,很可能会一直打开,既占用了通道和端口,还可能出现资源的浪费,从而影响系统的性能和稳定性。

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

  1. var myClient = new MyClient();  
  2. try  
  3. {  
  4. //其他代码  
  5. myClient.Close();  
  6. }  
  7. catch (CommunicationException)  
  8. {  
  9. myClient.Abort();  
  10. }  
  11. catch (TimeoutException)  
  12. {  
  13. myClient.Abort();  
  14. }  
  15. catch (Exception)  
  16. {  
  17. myClient.Abort();  
  18. throw;  

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

  1. public static class Extensions  
  2. {  
  3. public static void CloseConnection(this 
    ICommunicationObject myServiceClient)  
  4. {  
  5. if (myServiceClient.State != CommunicationState.Opened)  
  6. {  
  7. return;  
  8. }  
  9. try  
  10. {  
  11. myServiceClient.Close();  
  12. }  
  13. catch (CommunicationException ex)  
  14. {  
  15. Debug.Print(ex.ToString());  
  16. myServiceClient.Abort();  
  17. }  
  18. catch (TimeoutException ex)  
  19. {  
  20. Debug.Print(ex.ToString());  
  21. myServiceClient.Abort();  
  22. }  
  23. catch (Exception ex)  
  24. {  
  25. Debug.Print(ex.ToString());  
  26. myServiceClient.Abort();  
  27. throw;  
  28. }  
  29. }  

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

  1. public class Util  
  2. {  
  3. public static void Using<T>(T client, Action action)  
  4. where T : ICommunicationObject  
  5. {  
  6. try  
  7. {  
  8. action(client);  
  9. client.Close();  
  10. }  
  11. catch (CommunicationException)  
  12. {  
  13. client.Abort();  
  14. }  
  15. catch (TimeoutException)  
  16. {  
  17. client.Abort();  
  18. }  
  19. catch (Exception)  
  20. {  
  21. client.Abort();  
  22. throw;  
  23. }  
  24. }  

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

  1. Util.Using(new MyClient(), client => 
  2. {  
  3. client.SomeWCFOperation();  
  4. //其他代码;  
  5. }); 

还有一种方法是定义一个自己的ChannelFactory,让其实现WCF IDisposable接口,并作为ChannelFactory的Wrapper类。在该类中定义Close()和Dispose()方法时,考虑到异常抛出的情况,并在异常抛出时调用Abort()方法。这样我们就可以在using中使用自定义的ChannelFactory类。例如:

  1. public class MyChannelFactory:IDisposable  
  2. {  
  3. private ChannelFactory m_innerFactory;  
  4. public MyChannelFactory(ChannelFactory factory)  
  5. {  
  6. m_innerFactory = factory;  
  7. }  
  8. ~MyChannelFactory()  
  9. {  
  10. Dispose(false);  
  11. }  
  12. public void Close()  
  13. {  
  14. Close(TimeSpan.FromSeconds(10));  
  15. }  
  16. public void Close(TimeSpan span)  
  17. {  
  18. if (m_innerFactory != null)  
  19. {  
  20. if (m_innerFactory.State != CommunicationState.Opened)  
  21. {  
  22. return;  
  23. }  
  24. try  
  25. {  
  26. m_innerFactory.Close(span);  
  27. }  
  28. catch (CommunicationException)  
  29. {  
  30. m_innerFactory.Abort();  
  31. }  
  32. catch (TimeOutException)  
  33. {  
  34. m_innerFactory.Abort();  
  35. }  
  36. catch (Exception)  
  37. {  
  38. m_innerFactory.Abort();  
  39. throw;  
  40. }  
  41. }  
  42. }  
  43. private void Dispose(booling disposing)  
  44. {  
  45. if (disposing)  
  46. {  
  47. Close();  
  48. }  
  49. }  
  50. void IDisposable.Dispose()  
  51. {  
  52. Dispose(true);  
  53. GC.SuppressFinalize(this);  
  54. }  

对WCF IDisposable接口的相关介绍就为大家介绍到这里。

【编辑推荐】

  1. WCF REST正确定义方法介绍
  2. WCF消息模式基本内容简述
  3. WCF通道具体应用技巧分享
  4. WCF体系结构基本概念分享
  5. WCF调用服务异常基本解决方案介绍
责任编辑:曹凯 来源: CSDN
相关推荐

2010-02-26 10:56:06

WCF Stream

2009-08-31 16:48:02

C#实现IDispos

2010-02-22 11:25:50

WCF DateSet

2013-09-02 16:04:20

Windows

2010-01-26 10:38:56

Android消息传递

2010-02-22 15:00:02

WCF信道工厂

2010-03-02 17:35:20

WCF服务加载

2017-11-07 22:19:55

iOS 苹果App

2010-05-31 15:49:29

MySQL临时表

2010-02-03 17:39:21

2010-02-03 09:58:33

全光交换机

2019-09-04 14:30:54

Nginx功能服务器

2010-02-25 11:23:29

WCF返回自定义格式

2009-12-08 14:28:16

XTemplate +

2010-02-23 09:51:32

WCF MTOM

2023-10-27 08:59:00

网络wiresharkIO

2009-11-09 16:25:24

WCF Data Co

2009-12-04 17:35:51

WCF 服务

2010-02-25 13:35:27

WCF tcpTrac

2009-05-18 16:59:42

代码PHP编码
点赞
收藏

51CTO技术栈公众号