我有以下代码
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
该dispose()
方法在using
语句括号的末尾调用}
对吗?自从我 return
在using
声明末尾之前,将MemoryStream
正确处置该对象吗?这里会发生什么?
我有以下代码
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
该dispose()
方法在using
语句括号的末尾调用}
对吗?自从我 return
在using
声明末尾之前,将MemoryStream
正确处置该对象吗?这里会发生什么?
Answers:
是的,Dispose
将被呼叫。一旦执行离开了using
块的范围,就会立即调用它,无论离开块是用什么方式进行的,无论是块执行的结束,return
语句还是异常。
正如@Noldorin正确指出的那样,using
在代码中使用代码块被编译为try
/ finally
,并在代码块中Dispose
被调用finally
。例如下面的代码:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
有效地变为:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
因此,由于finally
保证了在try
块完成执行之后执行,所以无论其执行路径如何,Dispose
都可以确保调用它,无论如何。
有关更多信息,请参见MSDN文章。
附录:
需要注意的一点Dispose
是:由于可以被调用,因此Dispose
在实现时确保不抛出异常几乎总是一个好主意IDisposable
。不幸的是,有一些类核心库做在某些情况下抛出时Dispose
叫-我看着你,WCF服务参考/客户端代理!-并且发生这种情况时,如果Dispose
在异常堆栈展开期间调用了原始异常,则可能非常困难,因为原始异常会被吞咽而偏向于Dispose
调用生成的新异常。这可能令人发疯。还是那令人沮丧的发疯?两者之一。也许两者都有。
Dispose
并最终调用了in,因此它有效地解决了finally
您所描述的的实现。
using
语句的行为完全类似于try ... finally
块,因此将始终在任何代码退出路径上执行。但是,我相信它们会受到极少数很少finally
调用块的情况的影响。我可以记住的一个示例是,前台线程是否在后台线程处于活动状态时退出:除GC外的所有线程都已暂停,这意味着finally
不运行块。
显而易见的编辑:它们的行为与使它们处理IDisposable对象d'oh的逻辑相同。
奖励内容:它们可以堆叠(类型不同):
using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{
}
并以逗号分隔(类型相同):
using (SqlCommand comm = new SqlCommand("", conn),
SqlCommand comm2 = new SqlCommand("", conn))
{
}
您的MemoryStream对象将被正确处理,无需担心。