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 次 |
| 最近记录: |