C#-C#中的Dispose模式

Posted 叮呤咣啷品

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#-C#中的Dispose模式相关的知识,希望对你有一定的参考价值。

C#中的资源

在我们的程序中,使用资源后,需要释放。那么在C#中的每一种资源,可以分为两类:

- 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象;

- 非托管资源:不受CLR管理的对象,windows内核对象,如文件、数据库连接、套接字、COM对象等;


在我们的程序中,使用到了非托管资源,或者托管资源,最后都需要释放。针对托管资源,DotNet的垃圾回收器会自动地回收托管资源,而非托管的资源,则需要自己进行处理。


那么,我们可以使用C#的Dispose模式来方便地释放这些资源。


Disposal模式

要采用Dispose模式,需要让类型继承接口IDisposable,其标示了该类型是需要显式释放资源的,你需要调用我的Dispose方法。


namespace System

{

    //

    // 摘要:

    //     定义一种释放分配的资源的方法。

    [ComVisible(true)]

    public interface IDisposable

    {

        //

        // 摘要:

        //     执行与释放或重置非托管资源相关的应用程序定义的任务。

        void Dispose();

    }

}

可见,IDisposable接口很简单。


VS对IDisposable接口实现的支持

在VS.net中,对IDispose模式实现支持的非常好。可以自动生成代码框架。

看看自动生成的代码

#region IDisposable Support

private bool disposedValue = false; // 要检测冗余调用


protected virtual void Dispose(bool disposing)

{

    if (!disposedValue)

    {

        if (disposing)

        {

            // TODO: 释放托管状态(托管对象)。

        }


        // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。

        // TODO: 将大型字段设置为 null。


        disposedValue = true;

    }

}


// TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。

// ~ResourceMgr() {

//   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。

//   Dispose(false);

// }


// 添加此代码以正确实现可处置模式。

public void Dispose()

{

    // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。

    Dispose(true);

    // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。

    // GC.SuppressFinalize(this);

}

#endregion


代码中包含了 IDisposable的Dispose()方法,和其调用的protected virtual void Dispose(bool disposing)实现方法。

Dispose(bool)定义为protected virtual,可以在子类中进行override。


简单解释

实现方法借助了一个disposedValue标示变量,在接口的Dispose方法实现中,使用参数true来调用Dispose(bool)进行真正的释放操作,在操作完成后,disposedValue置为true,标示完成了Dispose;如果再次调用,就直接跳过。


结合 Finalize Method

一般,我们在析构器中进行清理的工作,这就是C#的Finalize方法。


~Object ();


我们可以在析构器Finalize方法中,进行必要的清理工作,以防止调用方没有使用Dispose来正确地释放资源。但要注意和Dispose的正确处理,防止多次释放的错误。


最简单地使用using语句

来自MS的示例:

using System;

using System.IO;

using System.Text.RegularExpressions;


public class WordCount

{

   private String filename = String.Empty;

   private int nWords = 0;

   private String pattern = @"\b\w+\b"; 


   public WordCount(string filename)

   {

      if (! File.Exists(filename))

         throw new FileNotFoundException("The file does not exist.");


      this.filename = filename;

      string txt = String.Empty;

      using (StreamReader sr = new StreamReader(filename)) {

         txt = sr.ReadToEnd();

      }

      nWords = Regex.Matches(txt, pattern).Count;

   }


   public string FullName

   { get { return filename; } }


   public string Name

   { get { return Path.GetFileName(filename); } }


   public int Count 

   { get { return nWords; } }

}  


使用using(resource) { ... },系统会隐式地调用对应资源的Dispose()方法来释放资源。


————————————————

版权声明:本文为CSDN博主「whereismatrix」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/whereismatrix/article/details/77870556


以上是关于C#-C#中的Dispose模式的主要内容,如果未能解决你的问题,请参考以下文章

关于 C# Dispose Pattern 的具体问题

csharp C#代码片段 - 使类成为Singleton模式。 (C#4.0+)https://heiswayi.github.io/2016/simple-singleton-pattern-us

C 中的共享内存代码片段

Dispose() 用于清理托管资源?

如何优化C ++代码的以下片段 - 卷中的零交叉

C#using()是啥意思