首先说一下 关于数据的这几个概念
一:资源回收就是把不用的占用给清掉 类似清空回收站操作 分为自动操作(托管) 和手动 操作(非托管)
1:如何知道是否是托管和非托管?
在C/C++中,资源都是需要手动释放的,比如,你new了一个指针,用过之后就需要delete掉,否则就会造成内存泄露。
C#中的每一种类型都是一种资源,而资源又分为托管资源和非托管资源。
托管资源:由CLR管理分配和释放的资源,也就是我们直接new出来的对象,是CLR直接进行分配空间,分配的资源一般会自动由平台的垃圾回收器GC释放;
非托管资源:不受CLR控制的资源,也就是不属于.NET本身的功能,往往是通过调用跨平台程序集(如C++)或者操作系统提供的一些接口,比如Windows内核对象、文件操作、数据库连接、socket、Win32API、网络,如System.IO.StreamReader等各种流、各种连接所分配的资源,需要显式调用Close()或Dispose()释放,这种资源就叫做非托管资源。
也可以理解为IDisposable 继承这个接口的类 都是非托管 需要手动释放资源
还好.net
Framework提供了Finalize()方法,它允许在垃圾回收器回收该类资源时,适当的清理非托管资源
这些了解下就行。跟析构函数回收有关。
在MSDN Library 中搜索Finalize将会发现很多类似的主题,这里列举几种常见的非托管资源:
ApplicationContext,Brush,Component,ComponentDesigner,Container,Context,Cursor,FileStream,Fon
t,Icon,Image,Matrix,Object,OdbcDataReader,OleDBDataReader,Pen,Regex,Socket,StreamWriter,Time
r,Tooltip 等等资源。
2:如何释放资源?
像之前说的,托管资源是有系统垃圾回收器GC 去释放的
当满足以下条件之一时,GC才会工作:
-
系统具有较低的物理内存;
-
由托管堆上已分配的对象使用的内存超出了可接受的范围;
-
手动调用GC.Collect方法,但几乎所有的情况下,我们都不必调用,因为垃圾回收器会自动调用它,但在上面的例子中,为了体验一下不及时回收垃圾带来的危害,所以手动调用了GC.Collect,大家也可以仔细体会一下运行这个方法带来的不同。
GC还有个“代”的概念,一共分3代:0代、1代、2代。而这三代,相当于是三个队列容器,第0代包含的是一些短期生存的对象,当方法执行完后,对象就被丢到了GC的第0代,但不进行垃圾回收,只有当第0代满了的时候,系统认为此时满足了低内存的条件,才会触发垃圾回收事件。所以我们永远不知道什么时候被回收掉,在回收之前,它实际上已经没有用处了,但始终占着系统资源不放(占着茅坑不拉屎),这对系统来说是种极大的浪费,而且这种浪费还会干扰整个系统的运行,由于它始终占着资源,就导致了我们不能再对文件进行访问了。
所以其实还是手动GC.Collect 是立马就释放的。
但是基本上不需要去手动GC.Collect去手动释放 托管的资源 让CLR去管就好了
非托管资源是需要我们显式的手动去释放的
通常我们会使用 using(实例化对象){ } 或者使用try catch finally 的finally 去使用Dispose() 释放资源
using的做法就是作用域结束自动去使用Dispose()释放资源
查看托管非托管区别:https://www.cnblogs.com/qtiger/p/11176575.html
二:捕获异常就是 将可能出现的未知错误捕获 try catch finally
一般情况 要么是结合 using 释放资源加异常捕获 要么就是不使用using 但是finally里面去Dispose() 释放资源
using (var tran = DbContext.Database.BeginTransaction())
{
try
{
DbContext.TourOrderTravelAgentCodes.Attach(mod);
DbContext.Entry(mod).Property(t => t.AgentEmailAddress).IsModified = true;
DbContext.SaveChanges();
tran.Commit();
isSuccess = true;
}
catch (Exception)
{
tran.Rollback();
isSuccess = false;
}
finally
{
}
}