NLV*_*NLV 112 .net c# dispose idisposable using-statement
我有以下代码
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
Run Code Online (Sandbox Code Playgroud)
dispose()
在using
语句括号结束时调用该方法}
对吗?由于我 return
在using
声明结束之前,MemoryStream
对象是否会被妥善处理?这里发生了什么?
Ran*_*pho 162
是的,Dispose
将被召集.一旦执行离开using
块的范围,就会调用它,无论它离开块的方式是什么,无论是块的执行结束,return
语句还是异常.
正如@Noldorin正确指出的那样,using
在代码中使用块被编译到try
/中finally
,并Dispose
在finally
块中调用.例如,以下代码:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有效地变成:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
因此,由于finally
保证在try
块完成执行后执行,无论其执行路径如何,Dispose
都可以保证被调用,无论如何.
有关详细信息,请参阅此MSDN文章.
附录:
添加一点注意事项:因为Dispose
保证会被调用,所以确保Dispose
在实现时永远不会抛出异常几乎总是一个好主意IDisposable
.不幸的是,核心库中有一些类在调用某些情况时会抛出Dispose
- 我在看着你,WCF服务参考/客户端代理!- 当发生这种情况时,如果Dispose
在异常堆栈展开期间调用,则跟踪原始异常可能非常困难,因为原始异常被吞下以支持Dispose
调用生成的新异常.这可能令人沮丧.还是令人沮丧地发疯?两个中的一个.也许两者.
Ada*_*rth 18
using
语句的行为与try ... finally
块完全相同,因此将始终在任何代码出口路径上执行.但是,我相信它们会受到极少数罕见的情况的影响finally
.我记得的一个例子是前台线程在后台线程处于活动状态时退出:除了GC之外的所有线程都被暂停,这意味着finally
块不会运行.
显而易见的编辑:它们的行为与允许它们处理IDisposable对象的逻辑相同,但是哦.
奖励内容:它们可以堆叠(类型不同):
using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{
}
Run Code Online (Sandbox Code Playgroud)
并且还以逗号分隔(类型相同):
using (SqlCommand comm = new SqlCommand("", conn),
SqlCommand comm2 = new SqlCommand("", conn))
{
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
26113 次 |
最近记录: |