浅析C# Dispose方法的实现

C# Dispose方法的理解是什么呢?类型的Dispose方法应释放它拥有的所有资源。它还应该通过调用其父类型的Dispose方法释放其基类型拥有的所有资源。该父类型的 Dispose 方法应该释放它拥有的所有资源并同样也调用其父类型的 Dispose 方法,从而在整个基类型层次结构中传播此模式。若要确保始终正确地清理资源,Dispose 方法应该可以被多次调用而不引发任何异常。

专注于为中小企业提供网站制作、成都网站制作服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业天台免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。

Dispose 方法应该为它处置的对象调用 GC.SuppressFinalize 方法。如果对象当前在终止队列中,GC.SuppressFinalize 防止其 Finalize 方法被调用。请记住,执行 Finalize 方法会大大减损性能。如果您的 Dispose 方法已经完成了清理对象的工作,那么垃圾回收器就不必再调用对象的 Finalize 方法。

C# Dispose方法的实现时注意

为 System.GC.KeepAlive(System.Object) 方法提供的代码示例演示了强行垃圾回收如何在回收对象的成员仍在执行时引起终结器运行。在较长的Dispose方法末尾***调用KeepAlive方法。

下面的代码示例旨在阐释用于为封装了非托管资源的类实现Dispose方法的建议设计模式。整个 .NET Framework 中都实现了此模式。

资源类通常是从复杂的本机类或 API 派生的,而且必须进行相应的自定义。使用这一代码模式作为创建资源类的一个起始点,并根据封装的资源提供必要的自定义。不能编译该示例,也不能将其直接用于应用程序。

在此示例中,基类 BaseResource 实现可由该类的用户调用的公共 Dispose 方法。而该方法又调用 virtual Dispose(bool disposing) 方法(Visual Basic 中为 virtual Dispose(disposing As Boolean))。根据调用方的标识传递 true 或 false。以虚 Dispose 方法为对象执行适当的清理代码。

Dispose(bool disposing) 以两种截然不同的方案执行。如果 disposing 等于 true,则该方法已由用户的代码直接调用或间接调用,并且可释放托管资源和非托管资源。如果 disposing 等于 false,则该方法已由运行库从终结器内部调用,并且只能释放非托管资源。因为终结器不会以任意特定的顺序执行,所以当对象正在执行其终止代码时,不应引用其他对象。如果正在执行的终结器引用了另一个已经终止的对象,则该正在执行的终结器将失败。

基类提供的 Finalize 方法或析构函数在未能调用 Dispose 的情况下充当防护措施。Finalize 方法调用带有参数的 Dispose 方法,同时传递 false。不应在 Finalize 方法内重新创建 Dispose 清理代码。调用 Dispose(false) 可以优化代码的可读性和可维护性。

类 MyResourceWrapper 阐释如何使用 Dispose 从实现资源管理的类派生。MyResourceWrapper 重写 virtual Dispose(bool disposing) 方法并为其创建的托管和非托管资源提供清理代码。MyResourceWrapper 还对其基类 BaseResource 调用 Dispose 以确保其基类能够适当地进行清理。请注意,派生类 MyResourceWrapper 没有不带参数的 Finalize 方法或 Dispose 方法,因为这两个方法从基类 BaseResource 继承这些参数。

C# Dispose方法的实现时注意

此示例中的 protected Dispose(bool disposing) 方法不强制线程安全,因为无法从用户线程和终结器线程同时调用该方法。另外,使用 BaseResource 的客户端应用程序应从不允许多个用户线程同时调用 protected Dispose(bool disposing) 方法。应用程序或类库的设计原则为:应用程序或类库应只允许一个线程拥有资源的生存期,并且应在不再需要资源时调用 Dispose。根据资源的不同,在处置资源时进行异步线程访问可能会带来安全风险。开发人员应仔细检查自己的代码,以确定***的方法来强制线程安全

C# Dispose方法的实现实例

 
 
 
  1. // Design pattern for the base class.  
  2. // By implementing IDisposable, you are announcing that instances  
  3. // of this type allocate scarce resources.  
  4. public class BaseResource: IDisposable  
  5. {  
  6. // Pointer to an external unmanaged resource.  
  7. private IntPtr handle;  
  8. // Other managed resource this class uses.  
  9. private Component Components;  
  10. // Track whether Dispose has been called.  
  11. private bool disposed = false;  
  12.  
  13. // Constructor for the BaseResource object.  
  14. public BaseResource()  
  15. {  
  16. // Insert appropriate constructor code here.  
  17. }  
  18.  
  19. // Implement IDisposable.  
  20. // Do not make this method virtual.  
  21. // A derived class should not be able to override this method.  
  22. public void Dispose()  
  23. {  
  24. Dispose(true);  
  25. // Take yourself off the Finalization queue   
  26. // to prevent finalization code for this object  
  27. // from executing a second time.  
  28. GC.SuppressFinalize(this);  
  29. }  
  30.  
  31. // Dispose(bool disposing) executes in two distinct scenarios.  
  32. // If disposing equals true, the method has been called directly  
  33. // or indirectly by a user's code. Managed and unmanaged resources  
  34. // can be disposed.  
  35. // If disposing equals false, the method has been called by the   
  36. // runtime from inside the finalizer and you should not reference   
  37. // other objects. Only unmanaged resources can be disposed.  
  38. protected virtual void Dispose(bool disposing)  
  39. {  
  40. // Check to see if Dispose has already been called.  
  41. if(!this.disposed)  
  42. {  
  43. // If disposing equals true, dispose all managed   
  44. // and unmanaged resources.  
  45. if(disposing)  
  46. {  
  47. // Dispose managed resources.  
  48. Components.Dispose();  
  49. }  
  50. // Release unmanaged resources. If disposing is false,   
  51. // only the following code is executed.  
  52. CloseHandle(handle);  
  53. handle = IntPtr.Zero;  
  54. // Note that this is not thread safe.  
  55. // Another thread could start disposing the object  
  56. // after the managed resources are disposed,  
  57. // but before the disposed flag is set to true.  
  58. // If thread safety is necessary, it must be  
  59. // implemented by the client.  
  60.  
  61. }  
  62. disposed = true;  
  63. }  
  64.  
  65. // Use C# destructor syntax for finalization code.  
  66. // This destructor will run only if the Dispose method   
  67. // does not get called.  
  68. // It gives your base class the opportunity to finalize.  
  69. // Do not provide destructors in types derived from this class.  
  70. ~BaseResource()  
  71. {  
  72. // Do not re-create Dispose clean-up code here.  
  73. // Calling Dispose(false) is optimal in terms of  
  74. // readability and maintainability.  
  75. Dispose(false);  
  76. }  
  77.  
  78. // Allow your Dispose method to be called multiple times,  
  79. // but throw an exception if the object has been disposed.  
  80. // Whenever you do something with this class,   
  81. // check to see if it has been disposed.  
  82. public void DoSomething()  
  83. {  
  84. if(this.disposed)  
  85. {  
  86. throw new ObjectDisposedException();  
  87. }  
  88. }  
  89. }  
  90.  
  91. // Design pattern for a derived class.  
  92. // Note that this derived class inherently implements the   
  93. // IDisposable interface because it is implemented in the base class.  
  94. public class MyResourceWrapper: BaseResource  
  95. {  
  96. // A managed resource that you add in this derived class.  
  97. private ManagedResource addedManaged;  
  98. // A native unmanaged resource that you add in this derived class.  
  99. private NativeResource addedNative;  
  100. private bool disposed = false;  
  101.  
  102.   // Constructor for this object.  
  103. public MyResourceWrapper()  
  104. {  
  105. // Insert appropriate constructor code here.  
  106. }  
  107.  
  108. protected override void Dispose(bool disposing)  
  109. {  
  110. if(!this.disposed)  
  111. {  
  112. try 
  113. {  
  114. if(disposing)  
  115. {  
  116. // Release the managed resources you added in  
  117. // this derived class here.  
  118. addedManaged.Dispose();  
  119. }  
  120. // Release the native unmanaged resources you added  
  121. // in this derived class here.  
  122. CloseHandle(addedNative);  
  123. this.disposed = true;  
  124. }  
  125. finally 
  126. {  
  127. // Call Dispose on your base class.  
  128. base.Dispose(disposing);  
  129. }  
  130. }  
  131. }  
  132. }  
  133.  
  134. // This derived class does not have a Finalize method  
  135. // or a Dispose method without parameters because it inherits   
  136. // them from the base class.  

C# Dispose方法的实现以及C# Dispose方法的一些基本内容就向你介绍到这里,希望对你了解和学习C# Dispose方法有所帮助。

【编辑推荐】

  1. C#窗体设计操作浅析
  2. C#窗体设计器开发实例详解
  3. C#窗体移动实例解析
  4. C#透明窗体代码详解
  5. C#透明窗体及按钮的效果浅析

本文名称:浅析C# Dispose方法的实现
当前URL:http://www.shufengxianlan.com/qtweb/news39/118739.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联