将不确定变为确定~程序是否真的Dispose了
2012-05-08 16:46
218 查看
回到目录
首先将来说一下Dispose是什么东西吧,对于我们使用非托管的资源时,需要自己去实现Dispose这个方法,它的含义就是释放使用的内存空间。
例如Stream这个类型,它就是一个非托管类型,它会实现一个IDisposable接口,来实现Dispose方法
像TransactionScope,.net事务,它也是一个非托管的,也就是说,我们在使用完事务后,需要自己去进行Dispose()操作,下面问题就来了,这个Dispose写在哪里合适呢?
注意看这段代码:
这是非常标准的写到,完成一个订单处理的过程,它将处理订单,网站支付明细及网站总余额写在了一个事务里,这当然是没有问题的,注意看Dispose的位置,写在了finally{}里,这也是对的,当try{}完成后,将会执行finally片断,但注意catch{}段,它进行所有异常的捕捉,并进行抛出,好了,如果这个try{}段出现了异常,那finally{}段是否会执行吗?也就是dispose是否会被执行呢?
经过我的测试,它有执行,但由于你使用了throw,所以网页直接黄屏了,所以,最好把catch段进行处理,你可以去把异常写到日志里,但有一点要注意,finally{}块里不要写可能会出现异常的代码,否则,会使你的事务资源永远得到不释放!
例如:
当然,这一般是由于编程习惯引起的,大家以后注意就行了,在finally里释放资源时,应该考虑异常进行一些必要的判断。
如果非要写在finally里,如果你的对象不能确定是否会发生异常,那就try,catch吧,看代码:
finally
{
try {
Insert(list.First().id); //如果list集合为空,那这行会出现异常,导致它下面的代码将不能被执行
}
catch (Exception e)
{
throw;
}
finally
{
trans.Dispose();
}
}
这样,trans.Dispose()也是会被执行的,也就是说,对于同一个try,catch,finally来说,finally是永远都会被执行的。
回到目录
首先将来说一下Dispose是什么东西吧,对于我们使用非托管的资源时,需要自己去实现Dispose这个方法,它的含义就是释放使用的内存空间。
例如Stream这个类型,它就是一个非托管类型,它会实现一个IDisposable接口,来实现Dispose方法
像TransactionScope,.net事务,它也是一个非托管的,也就是说,我们在使用完事务后,需要自己去进行Dispose()操作,下面问题就来了,这个Dispose写在哪里合适呢?
注意看这段代码:
using (TransactionScope trans = new TransactionScope()) { try { this.Update(order); new WebAccountRecordsRepository().Insert(new WebAccountRecords { }); new WebAccountBalancesRepository().Update(new WebAccountBalances { }); } catch (Exception e) { // vm.AddItem(e.Message); throw; } finally {
trans.Dispose(); } }
这是非常标准的写到,完成一个订单处理的过程,它将处理订单,网站支付明细及网站总余额写在了一个事务里,这当然是没有问题的,注意看Dispose的位置,写在了finally{}里,这也是对的,当try{}完成后,将会执行finally片断,但注意catch{}段,它进行所有异常的捕捉,并进行抛出,好了,如果这个try{}段出现了异常,那finally{}段是否会执行吗?也就是dispose是否会被执行呢?
经过我的测试,它有执行,但由于你使用了throw,所以网页直接黄屏了,所以,最好把catch段进行处理,你可以去把异常写到日志里,但有一点要注意,finally{}块里不要写可能会出现异常的代码,否则,会使你的事务资源永远得到不释放!
例如:
using (TransactionScope trans = new TransactionScope()) { try { this.Update(order); new WebAccountRecordsRepository().Insert(new WebAccountRecords { }); new WebAccountBalancesRepository().Update(new WebAccountBalances { }); } catch (Exception e) { // vm.AddItem(e.Message); throw; } finally {
Insert(list.First().id); //如果list集合为空,那这行会出现异常,导致它下面的代码将不能被执行
trans.Dispose();
}
}
当然,这一般是由于编程习惯引起的,大家以后注意就行了,在finally里释放资源时,应该考虑异常进行一些必要的判断。
如果非要写在finally里,如果你的对象不能确定是否会发生异常,那就try,catch吧,看代码:
finally
{
try {
Insert(list.First().id); //如果list集合为空,那这行会出现异常,导致它下面的代码将不能被执行
}
catch (Exception e)
{
throw;
}
finally
{
trans.Dispose();
}
}
这样,trans.Dispose()也是会被执行的,也就是说,对于同一个try,catch,finally来说,finally是永远都会被执行的。
回到目录
相关文章推荐
- 将不确定变为确定~static被翻译成静态,你是否赞同
- 将不确定变为确定~Linq的Group是否可以根据多个字段进行分组
- 将不确定变为确定~头压缩是否有必要,MVC如何实现头压缩
- 将不确定变为确定~表达式树是否可以有个集合,条件过滤有了新方向
- 将不确定变为确定~表达式树是否可以有个集合,条件过滤有了新方向续(新增了OR和AND查询)
- 将不确定变为确定~Razor视图中是否可以嵌套JS代码
- 将不确定变为确定~SQLSERVER是否可以进行位运算?
- 将不确定变为确定~Linq-Distinct()方法是否可以对复杂结果集进行去重?
- 将不确定变为确定~老赵写的CodeTimer是代码性能测试的利器
- 将不确定变为确定~MVC3的ValidateInput属性失灵了
- 将不确定变为确定~DAL层向BLL层返回数据用IEnumerable<T>还是IQueryable<T>
- 将不确定变为确定~DateTime.MinValue和MaxValue引发的异常
- 将不确定变为确定系列~目录(“机器最能证明一切”)
- 将不确定变为确定~为什么发布项目时用release环境更好些
- 将不确定变为确定~开发人员应该明确知道跨域Post的问题