c# 非托管资源的释放(析构函数、Dispose)

本文介绍了C#中非托管资源的管理,包括使用析构函数和IDisposable接口进行资源清理的方法。析构函数虽能确保资源清理,但执行时机不确定;IDisposable接口则提供更明确的释放机制,推荐使用Dispose方法配合using语句进行资源控制。
摘要由CSDN通过智能技术生成
资源类型

托管资源:由CLR建立和释放

非托管资源:资源的建立和释放不经CLR管理。好比IO、网络链接、数据库链接等等。须要开发人员手动释放。

如何释放非托管资源
方法1.声明一个析构函数,作为类的成员函数

C#编译器在编译析构函数时,会隐式把析构函数的代码编译为等价于重写Finalize()方法的代码,从而确保执行父类的Finalize方法。

protected override void Finalize()  

{  

    try

    {

        // Cleanup statements...   

    }     

    finally

    {

        base.Finalize();  

    }

}

优点:

资源管理: 提供了一种机制,确保在对象生命周期结束时进行资源清理。

自动执行: 由垃圾回收器自动调用,无需程序员手动介入,减少出错的可能性。

缺点:

  1. 无法确定c#对象的析构函数何时执行。
  2. C#析构函数的实现会延迟对象最终从内存中删除的时间。

结论:尽量避免使用析构函数。C#中通常更推荐使用IDisposable接口和Dispose方法来进行资源管理。

方法2.在类中实现system.IDispose

微软提供了IDispose接口,其中只声明了一个void的Dispose()虚函数方法。并且还为实现了IDispose接口的类提供了using释放资源的语法糖。

在实际使用上,使用实现IDispose接口和析构函数的双重实现机制。

1.继承IDispose接口的类,其析构函数调用了Dispose(false)方法,所以会释放资源。但是回收的时间不定、顺序不定、线程不定。因此析构函数中调用Dispose只是一个保险措施,并不能代替手动释放资源。

2.在自定义的类,并且继承IDisposable接口的时候,重写虚函数Dispose,

并且新建带参数的Dispose函数,在该函数实现释放资源。

public class Foo: IDisposable

{

bool m_disposed = false;//表示对象是否已经被清理

public void Dispose()

{

Dispose(true );

GC.SuppressFinalize(this);//意味着垃圾收集器认为这个对象根本就没有析构函数

}

protected virtual void Dispose(bool disposing)

{

if (!m_disposed)

{

if (disposing)    

{

//   //释放一些继承了IDisposable 的托管资源。一般很少

}

//在这里释放释放托管资源

m_disposed = true;

}

}

    //析构函数,正常情况下调用了Dispose(),就不需要再执行析构函数。

 ~Foo()

    {

        Dispose(false);

    }

注意:正常情况下,需用户手动显示调用Dispose()方法。或者使用using来释放资源,因为会自动调用Dispose()。

如果忘了using或显式调用Dispose(),那么析构函数就是兜底的了。

延伸:using 语句

使用using 语句,在一定的范围内有效,除了这个范围时,自动调用IDisposable的Dispose函数释放掉资源。

只有实现了IDisposable接口的类才可以使用。提供了机制保证Dispose方法被调用,无论using语句块顺利执行结束,还是抛出了一个异常。

using (var reader = new StringReader(manyLines))

{

    string? item;

    do

    {

        item = reader.ReadLine();

        Console.WriteLine(item);

    } while (item != null);

}

除了using可以达到这个目的意外,try finally也是可以的。如

    var reader = new StringReader(manyLines);

    try

    {

        string? item;

        do

        {

            item = reader.ReadLine();

            Console.WriteLine(item);

        } while (item != null);

    }

    finally

    {

        reader?.Dispose();

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值