使用“创建的资源的VB.NET范围”;新";子例程参数中的语句

使用“创建的资源的VB.NET范围”;新";子例程参数中的语句,vb.net,scope,new-operator,dispose,using,Vb.net,Scope,New Operator,Dispose,Using,我想知道,在VB.NET中: Using tBrush = New SolidBrush(UseColor) e.Graphics.FillRectangle(tBrush, someRect) End Using 相当于: e.Graphics.FillRectangle(New SolidBrush(UseColor), someRect) ? i、 e.在第二种情况下,SolidBrush是否会在FillRectangle完成后立即释放?简短回答,是的,它

我想知道,在VB.NET中:

Using tBrush = New SolidBrush(UseColor)      
  e.Graphics.FillRectangle(tBrush, someRect)    
End Using
相当于:

e.Graphics.FillRectangle(New SolidBrush(UseColor), someRect)   
?


i、 e.在第二种情况下,SolidBrush是否会在FillRectangle完成后立即释放?

简短回答,是的,它们是等效的。是的,第二个笔刷将被释放,在某个时候垃圾收集器将得到它


第一个是有趣的,但是,如果你想使用相同的画笔为几个矩形,而不是实例化一堆画笔。您可以通过将画笔作为命名变量启动并使用它直到超出范围(如果它更适合您的需要)来获得类似的结果。

这是正确的
使用
块创建自己的范围。。。但方法调用也是如此,如第二个示例中所示。Net非常聪明,知道画笔在其他任何地方都无法触及。因此,仅从范围上考虑,这两个选项非常接近,没有任何有意义的区别

但范围并不是这里的大问题。我们还需要讨论处置问题

在第一个示例中,一旦代码块完成,将立即处理画笔。在第二个示例中,刷子仅符合处置条件,但处置发生的确切时间仍不确定

通常,即使在第二种情况下,dispose也会相当快地发生,并且通常有足够的资源,如果稍微延迟一点,这并不重要。然而,有时可能需要一段时间,对于某些资源类型,或者在一些存在更多争用的环境中,任何潜在的延迟都可能是一个大问题。而且,由于您并不总是控制代码运行的环境,因此每当您有一个实现了
IDisposable
的类型时,最好使用


我还需要指出,处置与记忆没有任何关系。同样,两个示例共享相似的作用域,因此它们的内存都将由垃圾收集器以相似的方式回收。相反,本示例中由处置控制的资源是笔刷使用的资源。如果没有显式处理,只有当垃圾收集器最终开始调用对象的终结器时,才会释放该GDI句柄。在内存压力较低的系统上,这可能需要一段时间,因此需要一种不同的机制(
IDisposable
+
Using
)来回收它。

我的印象是Using/End Using会立即释放资源,而不是等待GC。不是这样吗?GC释放了不再被引用或不在范围内的资源,但它没有立即这样做。有一种方法,我不太熟悉,除了一个事实:当可用内存较少时,GC将“更频繁地出现”。在某些情况下,您可能会因此而有奇怪的行为,例如,如果尚未收集的未引用对象接收到事件并尝试对其执行操作。这是否会像第一个示例中那样立即进行处理:
Dim tBrush=New SolidBrush(useColour)e.Graphics.FillRectangle(tBrush,sometrect)tBrush.dispose()
@twhuttar仅当代码运行干净时。异常可能导致它错过Dispose调用<代码>使用
保证即使抛出异常也能进行处理。