正确实现 IDisposable 接口

虽然 .net 有垃圾回收机制(GC), 可自动进行大部分的资源清理工作,但开发人员仍旧应该养成良好的通过手动调用资源清理方法来进行资源回收的习惯, 让对象实现IDisposable接口正是 M$ 所推荐的, 该接口的原型为:
正确实现 IDisposable 接口正确实现 IDisposable 接口代码1//Summary:

2//Defines a method to release allocated unmanaged resources.

3[ComVisible(true)]

4publicinterfaceIDisposable

5{

6//Summary:

7//Performs application-defined tasks associated with freeing, releasing, or

8//resetting unmanaged resources.

9voidDispose();

10}

注:.net 内部也有传说中的”析构函数“,就是 Finalize(), 该函数由GC自动调用。
实现 Dispose 需要注意的是

1. 如果资源已手动释放过了,就应该通知GC,不要再对该对象执行 Finalize 操作


2. 确保重复执行 Dispose 时不会出错

根据以上规则, 简单的定义一个类 classSample
正确实现 IDisposable 接口正确实现 IDisposable 接口代码1publicclassclassSample : IDisposable

2{

3///



4///该对象是否已被销毁过

5///



6privatebooldisposed;

7

8///



9///这就是传说中的 Finalize函数,是不是和C++的析构函数很像?

10///



11~classSample()

12{

13Console.WriteLine("对象被销毁");

14

15Dispose(false);

16}

17

18publicvoidDispose()

19{

20Console.WriteLine("手动销毁对象");

21Dispose(true);

22//通知GC, 偶已经被销毁过了,可以不用再管偶了。。。

23GC.SuppressFinalize(this);

24}

25

26///



27///Dispose

28///



29///是否由程序直接调用

30protectedvoidDispose(booldisposing)

31{

32if(!disposed)

33{

34if(disposing)

35{

36//该函数为手动调用,此处可进行托管资源的清理

37//比如此类中有一个类型为 DataSet 的变量 dsData

38//此处可调用该对象的 Dispose 方法来清理托管资源

39dsData.Dispose();

40}

41

42//进行非托管资源的清理

43//非托管的资源主要为一些用 API 打开的文件句柄,设备场景句柄等

44//该类资源 GC 是无法管理的,只能依靠程序员自已释放

45//不同的资源, 释放方法不一样

46//例如:

47//释放文件句柄 (定义API的代码略。)

48CloseHandle(handle);

49//释放GDI 中的设备场景 (定义API的代码略。)

50ReleaseDC(hdc);

51}

52disposed=true;

53}

54}
注意protectedvoidDispose(booldisposing) 函数, 清理托管资源和非托管资源的代码位置不要写反了,否则当一个托管对象已经被GC回收后,再去调用它的Dispose 方法, 系统会触发一个 ObjectDisposedException 异常

到这里 ,一个简单的实现IDisposable 的类已经写好了, 再写段测试代码看看

privatevoidbutton1_Click(objectsender, EventArgs e)

{

classSample cls
=newclassSample();

}

点击按钮, 再关闭程序, 可看到 output 窗口中显示对象被销毁正确实现 IDisposable 接口说明 Finalize 函数被执行了

换一个

1privatevoidbutton1_Click(objectsender, EventArgs e)
2{

3classSample cls=newclassSample();

4cls.Dispose();

5}

再看 output 窗口中,只显示了”手动销毁对象“, 说明在手动执行Dispose 后,已正确通知GC,不再执行Finalize函数。


小技巧: 可使用 using 关键字来定义对象的生存期,


超出 using范围 后,如果对象实现了IDisposable接口, 系统会自动调用其 Dispose 方法, 是不是很方便。

1using(classSample cls=newclassSample())

2{

3}

看,我并没有调用 Dispose 方法, output 窗口中还是会显示 ”手动销毁对象“.

原文链接: https://www.cnblogs.com/xuhan/archive/2010/11/05/1869874.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17019

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午5:29
下一篇 2023年2月7日 下午5:29

相关推荐