我有这段代码:
using (var img = Bitmap.FromFile(path))
{
result = new Bitmap(img);
}
问题:
Bitmap
实例?还是等待垃圾收集?答案 0 :(得分:3)
您实际上有两个位图实例 - img
和result
。
img
将在using
块的末尾处理(我相信当前的线程)。编译器会在Dispose
块中为您插入finally
调用。
result
不会自动处理 - 无论消费结果都需要处理它。
另请注意,处理和垃圾收集是两回事 - Dispose
将立即清除所有非托管资源(在Bitmap的情况下,它将是底层图形对象)但是,任何托管的资源都将被垃圾收集,因为它们会在稍后的未确定时间内被收集。
答案 1 :(得分:2)
您的代码等同于以下(实际上编译器如何翻译代码):
try
{
var img = Bitmap.FromFile(path);
result = new Bitmap(img);
}
finally
{
img.Dispose();
}
请注意result
从未调用Dispose
,并且由调用代码来正确处理对象。
答案 2 :(得分:1)
既不是垃圾收集也不是处置。您编写这样的代码来创建位图的深层复制。与创建浅拷贝的Bitmap.Clone()
不同。您可以使用它来避免锁定路径文件。稍后当您尝试将图像保存回来时,此类锁定可能非常麻烦,因为GenericException失败。
Bitmap(Image)构造函数使用Graphics.DrawImage()创建副本。 img变量上的 using 语句释放对文件的锁定。
这并非完全没有麻烦btw,深度复制会花费大量内存,并且可能会在图像很大时显着增加进程的提交大小。或者换句话说,它很昂贵,你将冒着使用OutOfMemoryException进行程序轰炸的风险。还有一个缺陷,Bitmap(Image)构造函数忘记复制Image.HorizontalResolution和VerticalResolution属性。因此图像可能无法以相同的尺寸显示。
答案 3 :(得分:0)
using
是try/finally
模式的语法糖,在括号关闭后,Img.Dispose();
将在后面调用。
using (var img = Bitmap.FromFile(path))
{
result = new Bitmap(img);
} // here Dispose will be immediately called.
if you are using img/result here you will get an Exception.
线程与此事无关! Dispose始终在当前线程中调用。