using语句的记忆碎片

资源的清理using语句的用法

前言

垃圾回收是‘运行时’的一个重要的职责。但是,垃圾回收的宗旨是提高内存的利用。它不是用来清理文件的句柄、数据库链接字符串、端口或者其他有限资源的。

一、终结器的用途

终结器允许程序员编写代码来清理一个类的资源。但是,终结器不能从代码中显示的调用,而是由垃圾回收器负责对一个对象实例调用终结器。因此,开发者不能在编译时确定执行终结器的时间,唯一能确定的是终结器会在上次使用这个对象后,并在应用程序结束之前的某个时刻运行。
终结器的定义:

    public class TemporaryFileStream1
    {
        ~TemporaryFileStream1()
        {
            Close();
        }
        public FileStream Stream { get; set; }
        public FileInfo File { get; set; }
        public void Close()
        {
            if (Stream != null)
            {
                Stream.Close();
            }
            if (File != null)
            {
                File.Delete();
            }
        }
    }
终结器没有参数,所以终结器不能重载。终结器只能被垃圾回收器调用,因此为终结器添加修饰符没有任何的意义,并且终结器也不允许添加访问修饰符。基类的终结器会作为对象的终结器的一部分被调用。终结器主要负责释放像数据库连接和文件句柄这样的资源,这样的资源需要通过显示的行动来进行清理,而垃圾回收器是作为一个对资源清理的一个备用机制。假如使用某一个类开发者忘记显示调用必要的代码,就可以依赖垃圾回收器去调用终结器来清理资源,所以说假如我们自己做好显示调用方法来清理资源,那几乎用不到终结器来不确定的释放资源。由于确定性终结的重要性,基类库为这个使用模式包含了一个特殊的接口,而且c#已将这个模式集成到语言中来了。IDisposable接口用一个名为Dispose方法来定义这个模式的细节。
使用IDisposable清理资源:


    public class TemporaryFileStream2 : IDisposable
    {
        ~TemporaryFileStream2()
        {
            Close();
        }
        public FileStream Stream { get; set; }
        public FileInfo File { get; set; }
        public void Close()
        {
            if (Stream != null)
            {
                Stream.Close();
            }
            if (File != null)
            {
                File.Delete();
            }
        }
        //IDisposable定义的方法在基类中的实现
        public void Dispose()
        {
            Close();
        }
    }
    class Progrom
    {
        static void Search1()
        {
            TemporaryFileStream2 fileStream = new TemporaryFileStream2();
            //......
            //......
            fileStream.Dispose();
            //......
            //......
        }
    }

无论实现还是调用IDisposable接口,步骤都是十分的简单,然而还要记住一点:在实例化之后并在调用Dispose方法之前有可能出现一个异常,就不会调用显示的资源的清理的方法。为了避免这个情况,调用者需要实现一个try/finally块。但是,开发者可以不需要写一个这样的块。可以用using语句来实现这个功能。
执行using语句

    class Progrom
    {
        static void Search2()
        {
            using (TemporaryFileStream2 fileStream1 = new TemporaryFileStream2(), fileStream2 = new      TemporaryFileStream2())
            {
                //......
                //......
            }
        }
    }

上面的功能与写一个显示的try finally是一样的,总之using语句只是提供一个语法的捷径。在using语句中,可以实例化多个变量,只需用逗号分隔每一个变量。这里的关键在于,所有的变量都是具有相同的类型,而且都是实现了IDisposable。这一点要切记。


原文地址:https://www.cnblogs.com/lmfeng/p/2254453.html