.Net组件程序设计之对象生命周期

简介:

.Net组件程序设计之对象生命周期

 

  • .NET 垃圾回收

  • IDisposable()

  • Using语句

.NET 垃圾回收

是CLR管理着垃圾回收器,垃圾回收器监控着托管堆,而我们使用的对象以及系统启动是所需要的一些必备的对象信息都存在于托管堆上,CLR会维护着一个列表(对象引用信息列表). 这个列表里存放的信息就是对应着托管堆中所有对象的信息(引用、被引用信息)每当使用一个新的对象或者是改变一个现有对象的引用CLR都会更新 对象引用信息列表。那么回收器一般什么时候调用呢?

垃圾回收器大多数是在托管堆耗尽的情况下被触发使用 ,也可以通过代码来调用(下面会讲到).

在垃圾回收器调用的时候,会从(对象引用信息列表)开始遍历查看每个对象是否能够到达客户端(使用这些对象的应用程序),如果能够到达则这个对象就被标记可到达并且跳过它(查看对象是否有引用),继续的遍历下面,而且被标记的对象所引用的对象将不会被再次检查。当检查到对象没有引用这些对象的时候,则会回收这些对象,并且进行空间压缩,修改那些有引用对象的地址进行空间压缩。

IDisposable()

在.NET中给我们提供了IDispose接口就是用来释放资源的,看一段示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  1      public  interface  IMyinterface
  2     {
  3          void  DoSomeThing();
  4     }
  5      public  class  StydyClass:IMyinterface,IDisposable
  6     {
  7          public  void  Dispose()
  8         {
  9              //释放资源
10         }
11          public  void  DoSomeThing()
12         {
13              //do something
14         }
15     }

看一下客户端调用代码:

1
2
3
4
5
6
7
8
1 IMyinterface studyClass =  new  StudyClass();
2 studyClass.DoSomeThing();
4 IDisposable disposable = studyClass  as  IDisposable;
if  (disposable !=  null )
6 {
7    disposable.Dispose();
8 }

这种调用方式很安全啊,如果studyClass没有支持IDisposable,as操作符则会返回NULL值,看起来没什么问题, 但是如果客户端对象是共享的,有很多对象在使用它,那究竟由谁准确的来执行IDisposable.Dispose()。 如果在DoSomeThing()函数执行的时候发生一些错误,那么资源还会被释放吗?

Using语句

C# 支持Using语句,在使用Using语句的时候会帮我们生成一个使用Dispose()方法的try/finally块,当然你的对象必须先支持IDisposable才行。看一下示例代码:

1
2
3
4
using  (IMyinterface studyClass =  new  StudyClass())
2 {
3     studyClass.DoSomeThing();
4 }

如果这样写,编译是不会通过的,并且会提示你,using语句中使用的类型是必须可以隐式转换为System.IDisposable的。当然了, 也是有办法可以让这样的代码编译通过的,让IMyinterface接口也派生于IDisposable。 这样之后就可以这样来写代码:

1
2
3
4
5
6
7
8
9
10
   1 IMyinterface studyClass =  new  StudyClass();
  using  (studyClass  as  IDisposable)
  3 {
  4    studyClass.DoSomeThing();
  5 }
 
  using  (StudyClass studyClass =  new  StudyClass())
  8 {
  9    studyClass.DoSomeThing();
10 }

以上的书写方式都是可以实现的,上两段代码同等于下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
  1 StudyClass studyClass =  new  StudyClass();
  try
  3 {
  4    studyClass.DoSomeThing();
  5 }
  finally
  7 {
  8     if  (studyClass !=  null )
  9     {
10        IDisposable dis = studyClass;
11         dis.Dispose();
12     }
13 }

本篇的内容没有很复杂深奥,只是基础的讲解了一下对象的生命周期管理,还有一些深入的知识就不作讲解了,还有的就是我们在面向对象设计的时候,准备对一些重要的使用率较高的对象面向抽象设计的时候,尽量的让抽象对象来实现IDisposable接口,这样的话也不会出现上述内容中的错误信息。

 

 

 



     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1421931,如需转载请自行联系原作者





相关文章
|
前端开发 C# 数据库
.NET中使用BootstrapBlazor组件库Table实操篇
.NET中使用BootstrapBlazor组件库Table实操篇
438 0
|
开发框架 前端开发 .NET
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
365 0
|
10月前
|
存储 缓存
.NET 6中Startup.cs文件注入本地缓存策略与服务生命周期管理实践:AddTransient, AddScoped, AddSingleton。
记住,选择正确的服务生命周期并妥善管理它们是至关重要的,因为它们直接影响你的应用程序的性能和行为。就像一个成功的建筑工地,工具箱如果整理得当,工具选择和使用得当,工地的整体效率将会大大提高。
350 0
|
搜索推荐 API C#
.NET开源快速、强大、免费的电子表格组件
.NET开源快速、强大、免费的电子表格组件
306 0
.NET 4.0下实现.NET4.5的Task类相似功能组件
【10月更文挑战第29天】在.NET 4.0 环境下,可以使用 `BackgroundWorker` 类来实现类似于 .NET 4.5 中 `Task` 类的功能。`BackgroundWorker` 允许在后台执行耗时操作,同时不会阻塞用户界面线程,并支持进度报告和取消操作。尽管它有一些局限性,如复杂的事件处理模型和不灵活的任务管理方式,但在某些情况下仍能有效替代 `Task` 类。
234 0
|
存储 开发框架 前端开发
基于Lumisoft.NET组件,使用IMAP协议收取邮件
基于Lumisoft.NET组件,使用IMAP协议收取邮件
|
存储 对象存储 Python
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
|
NoSQL 大数据 Redis
分享5款.NET开源免费的Redis客户端组件库
分享5款.NET开源免费的Redis客户端组件库
321 1
|
开发框架 .NET API
ASP.NET Core Web中使用AutoMapper进行对象映射
ASP.NET Core Web中使用AutoMapper进行对象映射
276 1
|
SQL 开发框架 JavaScript
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
390 0