• C# IDisposable的理解


    C#里可以嵌入非托管代码,这就涉及到了这些代码资源的释放。以前总是看到别人的代码里那么写,也没有好好想想为什么,今天看了书,总结一下。

    资源释放分为两种:

    1. 托管的
    2. 非托管的

    两者的释放方式不一致:

    1. 没有非托管资源的,GC在运行时,会自动回收和释放;
    2. 含有非托管资源的,必须提供一个析构器,他们也会在内存里停留的时间会更长,最终被加入一个叫做finalization queue的结构,然后由GC在另一个线程释放;

    实现IDispose接口是一种标准的释放资源的方式,正确使用会减少很多的bug和因为资源释放而引起的问题。正如上面所说,包含了非托管资源的代码,是必须提供一个析构器的。这样做的目的,是为了保证类的使用者,即使没有显式地调用Dispose方法,也可以正确地释放资源。

    生产环境中的代码里,会有很多的继承,因此为了保证子类在调用时能够正确地执行父类的资源释放,在标准模式中,将真正的资源释放方法Dispose方法,抽象为一个virtual的方法,由子类去override,并在其中调用base的Dispose方法。

    释放资源的Dispose方法,应该完成以下几件事(引用Effective C#)

    1. 释放所有的非托管资源;
    2. 释放所有的托管资源;
    3. 设定一个标志,标志资源是否已经销毁;对于销毁的对象,仍旧调用,则应抛异常;
    4. 跳过终结操作,调用GC.SuppressFinalize(this)方法。

    以上,文字内容结束,基本的代码如下:

     1 using System;
     2 using System.Diagnostics;
     3 
     4 namespace Learn
     5 {
     6     class Program
     7     {
     8         private static int Cnt = 100000;
     9 
    10         static void Main(string[] args)
    11         {
    12             Stopwatch sw = new Stopwatch();
    13             sw.Start();
    14             for (int i = 0; i < Cnt; i++)
    15             {
    16                 IDisposeDerived de = new IDisposeDerived();
    17             }
    18             sw.Stop();
    19             Console.WriteLine("total time is: " + sw.ElapsedMilliseconds);
    20             Console.ReadLine();
    21         }
    22     }
    23 
    24     internal class IDisposeBase : IDisposable
    25     {
    26         // never add this unless unmanaged resources exist
    27         // cauz this will add extra burdon and make negative influence on performance
    28         //~IDisposeBase()
    29         //{
    30         //    Dispose(false);
    31         //}
    32 
    33         private bool AlreadyDisposed = false;
    34 
    35         public void Dispose()
    36         {
    37             Dispose(true);
    38             GC.SuppressFinalize(this);
    39         }
    40 
    41         protected virtual void Dispose(bool shouldDisposeManagedReources)
    42         {
    43             if (AlreadyDisposed)
    44                 return;
    45             if (shouldDisposeManagedReources)
    46             {
    47                 // dispose the managed resources
    48                 // release the events
    49                 // etc.
    50             }
    51             // dispose the unmanaged resources
    52 
    53             // set the flag
    54             AlreadyDisposed = true;
    55         }
    56 
    57         public void MethodForPublic()
    58         {
    59             if (AlreadyDisposed)
    60                 throw new Exception("object has been disposed!");
    61             // do the normal things
    62         }
    63     }
    64 
    65     internal class IDisposeDerived : IDisposeBase
    66     {
    67         //~IDisposeDerived()
    68         //{
    69         //    Dispose(false);
    70         //}
    71 
    72         private bool AlreadyDisposed = false;
    73 
    74         protected override void Dispose(bool shouldDisposeManagedReources)
    75         {
    76             if (AlreadyDisposed)
    77                 return;
    78             if (shouldDisposeManagedReources)
    79             {
    80                 // dispose managed resources
    81             }
    82             // dispose unmanaged resources
    83 
    84             // call the base's dispose method
    85             base.Dispose(shouldDisposeManagedReources);
    86 
    87             // set the flag
    88             AlreadyDisposed = true;
    89         }
    90     }
    91 }

    代码里增加了包含析构器的实现,可以对比一下,性能差异十分明显。

    无析构器的实现结果:

    有析构器的实现结果:

  • 相关阅读:
    C语言内存调试技巧—C语言最大难点揭秘
    include .h 以及.cpp的记录
    VS2010中<无法打开包括文件:“iostream.h”:>错误解决方法
    #include<iostream>与#include<iostream.h>的区别
    VS2013/2012 下无法打开 源 文件“stdafx.h”的解决方法
    【Oracle】Oracle日期格式详解
    【EasyUI】 日期格式化
    【TortoiseGit】TortoiseGit将本地库push到远端
    【Tomcat】解决Eclipse无法添加Tomcat Service问题
    【Tomcat】配置Tomcat
  • 原文地址:https://www.cnblogs.com/warnet/p/5084504.html
Copyright © 2020-2023  润新知