我有以下代码
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对象将被正确处理,无需担心。