4

我知道一个using块确保IDisposable正在“使用”的对象将在块的末尾被处置 - 但它是否保证在此之前不会处置该对象?

换句话说,如果我有:

using (new DisposableObject()) {
  // blah blah
}

我可以确定DisposableObject直到块结束时才会处理它,或者垃圾收集器是否会检测到我在块内没有处理它,并立即处理它?

4

3 回答 3

6

不,它没有。没有什么能阻止你这样做:

using(var myObject = new DisposableObject())
{
    myObject.Dispose();
}

在这种情况下究竟会发生什么取决于DisposableObject. Dispose它可能会抛出异常,或者它可能对被调用两次感到非常满意。

需要注意的是,对象处理和垃圾回收是完全不同的概念。仅仅因为一个对象被释放并不意味着它会被垃圾回收,仅仅因为一个对象被垃圾回收并不意味着它会被释放。

一旦对该对象的所有引用都被销毁或无法访问,则该对象可能会被垃圾回收。当代码在using-block 内运行时不会发生这种情况,因为块本身具有对该对象的引用。

于 2013-07-07T20:04:49.007 回答
4

您的对象只会被释放一次,并且在 using 块结束之前不会被 GC。

该规范保证当您拥有using (expression) statement并且表达式的类型是可为空的类型(调用它ResourceType)时,它会扩展为:

{
   ResourceType resource = expression;
   try {
      statement;
   }
   finally {
      if (resource != null) ((IDisposable)resource).Dispose();
   }
}

Dispose将在块的末尾调用一次,并且有一个本地生成的,它保留对您的一次性对象的引用。local 防止对象在 using 块结束之前被 GC。

于 2013-07-07T20:16:08.813 回答
2

我认为您更想了解垃圾收集而不是处置。

垃圾收集器不会收集using块内的对象。即使您专门调用了该Dispose方法,仍然有一个对其的活动引用,因此不会被收集。

为块生成的代码using以检查对象是否可以被释放结束,以便使用将在using块期间保持对象处于活动状态。

于 2013-07-07T20:14:23.180 回答