C#-终结器

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace 终结器
{
class Program
{

    /*
     * 终结器 (finalizer) 允许编写代码来清理类的资源
     * 和使用new 显式调用构造器不同,终结器不能从代码中显式调用,没有与new 对应的操作符,
     * 也不能在编译时确定执行终结器的时间,(也就是说不能人为的去确定终结器执行的时间)唯一能确定的是,
     * 终结器会在对象最后一次使用之后,并在程序正常关闭之前的某个时间运行。
     * 
     * 终结器声明要求 要在类名之前添加一个 ~ 字符
     * https://www.cnblogs.com/zhangq/p/3922123.html
     * 
     * 1)   垃圾回收过程中执行终结器的准确时间是不确定的。不保证资源在任何特定的时间都能释放,除非调用 Close 方法或 Dispose 方法。
     * 2)   即使一个对象引用另一个对象,也不能保证两个对象的终结器以任何特定的顺序运行。即,如果对象 A 具有对对象 B 的引用,并且两者都有终结器,则当对象 A 的终结器启动时,对象 B 可能已经终结了。
     * 3)   运行终结器的线程是未指定的。
     * 
     */
    static void Main(string[] args)
    {
        #region 终结器


        /*
        ExampleClass ex = new ExampleClass();
        ex.ShowDuration();
        GC.Collect();
        */
        #endregion
    }

}
#region 终结器
public class ExampleClass
{
    //提供一组可用于精确度量的方法和属性运行时间。
    System.Diagnostics.Stopwatch sw;

    public ExampleClass()
    {
        sw = System.Diagnostics.Stopwatch.StartNew();
        Console.WriteLine("实例化 object");
    }
    public void ShowDuration()
    {
        //一个只读的系统。表示所测量的总运行时间当前实例。 Elapsed
        Console.WriteLine("实例 {0} 存在时间 {1}", this, sw.Elapsed);
    }
    ~ExampleClass()
    {
        Console.WriteLine("销毁 object");
        sw.Stop();
        Console.WriteLine("实例 {0} 存在时间 {1}", this, sw.Elapsed);
    }
}
#endregion

#region IDisposable 资源释放
/*
 * 
 * https://www.cnblogs.com/wyt007/p/9304564.html
 * 
 * https://www.cnblogs.com/myzony/p/11712689.html
 * 
 * 
 * Dispose 清理与内存无关的资源(文件,图片,音频),这种资源不会被垃圾回收器隐式清理
 * 
 * 托管资源: 由CLR管理分配和释放的资源,也就是我们直接new出来的对象;
 *  
 *  
 * 通过实现 IDisposable 接口去实现释放非托管资源
 * 非托管资源不受CLR控制的资源,也就是不属于.NET本身的功能,
 * 往往是通过调用跨平台程序集(如C++)或者操作系统提供的一些接口,
 * 比如Windows内核对象、文件操作、数据库连接、socket、Win32API、网络等。
 * 
 * IDisposable 实现逻辑
 * 
 * 1. 实现dispose 方法
 * 2.提取一个受保护的dispose 虚方法 ,用来实现具体的释放资源的逻辑
 * 3.添加析构函数
 * 4.添加一个私有的bool 类型字段,作为释放资源的标志
 * 
 */
public class Myclass : IDisposable
{
    /// <summary>
    /// 模拟一个非托管资源
    /// </summary>
    // IntPtr 用于表示指针或句柄的平台特定类型
    // Marshal 提供了一个方法集,这些方法用于分配非托管内存、复制非托管内存块、将托管类型转换为非托管类型,此外还提供了在与非托管代码交互时使用的其他杂项方法。
    // AllocHGlobal 通过使用指定的字节数,从进程的非托管内存中分配内存。
    private IntPtr NR { get; set; } = System.Runtime.InteropServices.Marshal.AllocHGlobal(100);

    /// <summary>
    /// 一个托管资源 
    /// </summary>
    public Random random { get; set; } = new Random();

    /// <summary>
    /// 释放标志
    /// </summary>
    private bool disposed;
    /// <summary>
    /// 为了防止忘记显式的调用Dispose方法
    /// </summary>
    ~Myclass()
    {
        Dispose(false);
    }


    /// <summary>
    /// 重写 Dispose
    /// </summary>
    /// <param name="disposing"></param>
    protected virtual void Dispose(bool disposing)
    {
        if (disposed)
        {
            return;
        }
        //清理托管资源
        if (disposing)
        {
            if (!random.Equals(null))
            {
                random = null;
            }
        }
        //清理非托管资源
        if (NR != IntPtr.Zero)
        {
            //IntPtr.Zero 一个只读字段,代表已初始化为零的指针或句柄。
            // FreeHGlobal 释放以前从进程的非托管内存中分配的内存。
            Marshal.FreeHGlobal(NR);
            NR = IntPtr.Zero;
        }
        disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        // SuppressFinalize 请求系统不要调用指定对象的终结器。 通知垃圾回收器不再调用终结器
        GC.SuppressFinalize(this);

    }
}

public class Files
{
  public Files()
    {
        string s = @"C:\Users\Administrator\Desktop\VS_Git使用说明";
        byte[] ss = new byte[] { 1, 2, 3, 4 };
        System.IO.FileStream file = new FileStream("abc.text", FileMode.Create);

        file.Write(ss,0,ss.Length);
        File.Delete("abc.text");
        file.Dispose();

        /*
         * 使用suing 相当于在内部放置了一个try 
         * 用完就释放资源,换种方法说,他的声明周期只在这个方法里面
         */
        using (System.IO.FileStream fileStream = new FileStream("asd.text", FileMode.CreateNew))
        {

        } 
    }

    ~Files(){

    }
   
}



#endregion

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值