如果我使用语句结束前返回,会发生什么?请问处置被称为?被称为、语句、发生、结束

2023-09-02 01:46:30 作者:浮伤年华

我有以下code

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

配置()方法被调用在的使用语句括号结束} 吗?由于我返回使用语句的结束,将在的MemoryStream 对象得到妥善处置?这里会发生什么?

The dispose() method is called at the end of using statement braces } right? Since I return before the end of the using statement, will the MemoryStream object be disposed properly? What happens here?

推荐答案

处置将被调用。它一旦执行离开使用块的作用,被称为不管拿什么花了离开的块,无论是执行该块的结束时, 返回语句,或异常。

Yes, Dispose will be called. It's called as soon as the execution leaves the scope of the using block, regardless of what means it took to leave the block, be it the end of execution of the block, a return statement, or an exception.

由于@Noldorin正确地指出,使用code进行使用块被编译成尝试 / 最后,与处置被称为在最后块。例如下面的code:

As @Noldorin correctly points out, using a using block in code gets compiled into try/finally, with Dispose being called in the finally block. For example the following code:

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

实际上变成:

effectively becomes:

MemoryStream ms = new MemoryStream();
try
{
    // code
    return 0;
}
finally
{
    ms.Dispose();
}

所以,因为最后保证后执行尝试块执行结束,无论其执行路径,处置是保证被调用,不管是什么。

So, because finally is guaranteed to execute after the try block has finished execution, regardless of its execution path, Dispose is guaranteed to be called, no matter what.

有关详细信息,请参阅这个MSDN文章。

For more information, see this MSDN article.

附录:的 只是有一点需要注意补充:因为处置是保证被调用,它几乎总是一个好主意,以确保处置不会抛出,当你实现一个异常的IDisposable 。不幸的是,在核心库中的某些类的不的扔在某些情况下,当处置被称为 - 我看着你,WCF服务参考/客户端代理! - ,这时它可以是非常难以追查原始的异常,如果处置在一个异常堆栈展开叫,因为原始异常被吞噬赞成由处置调用产生新的异常。它可以是令人恼火令人沮丧。或者是令人沮丧的郁闷?一两个。也许两者兼而有之。

Addendum: Just a little caveat to add: because Dispose is guaranteed to be called, it's almost always a good idea to ensure that Dispose never throws an exception when you implement IDisposable. Unfortunately, there are some classes in the core library that do throw in certain circumstances when Dispose is called -- I'm looking at you, WCF Service Reference / Client Proxy! -- and when that happens it can be very difficult to track down the original exception if Dispose was called during an exception stack unwind, since the original exception gets swallowed in favor of the new exception generated by the Dispose call. It can be maddeningly frustrating. Or is that frustratingly maddening? One of the two. Maybe both.