2

我有这段代码:

using (var img = Bitmap.FromFile(path))
{
    result = new Bitmap(img);
}

问题:

  1. 实例是否Bitmap在使用结束时立即调用?还是在等待垃圾收集?
  2. 它是从当前线程还是从其他线程处理的?
4

4 回答 4

3

您实际上有两个Bitmap 实例 -imgresult.

img将在块的末尾被处理(我相信在当前线程上)using。编译器会为您在块中 插入一个Dispose调用。finally

result不会自动处理 - 任何消耗结果都需要处理它。

另请注意,处理和垃圾收集是两件不同的事情 -Dispose将立即清理任何非托管资源(在位图的情况下,它将是底层图形对象),但任何托管资源将在稍后的时间被垃圾收集,未确定的时间.

于 2013-09-06T16:10:24.853 回答
2

您的代码等效于以下代码(实际上是编译器翻译代码的方式):

try
{
    var img = Bitmap.FromFile(path);
    result = new Bitmap(img);
}
finally
{
    img.Dispose();
}

请注意,result从未Dispose调用过它,并且由调用代码正确处理对象。

于 2013-09-06T16:16:08.590 回答
1

它既不是垃圾收集也不是处置。您编写这样的代码来创建位图的深层副本。与Bitmap.Clone()创建浅拷贝不同。您使用它来避免锁定路径文件。稍后当您尝试将图像保存回来时,此类锁定可能会非常麻烦,这会失败并出现 GenericException。

Bitmap(Image) 构造函数使用 Graphics.DrawImage() 创建副本。img 变量上的using语句释放文件上的锁定。

顺便说一句,这并非完全没有问题,深拷贝会消耗大量内存,并且当图像很大时会显着增加进程的提交大小。或者换句话说,它很昂贵,并且您将面临程序因 OutOfMemoryException 被炸毁的风险。还有一个缺陷,Bitmap(Image) 构造函数忘记复制 Image.Horizo​​ntalResolution 和 VerticalResolution 属性。所以图像可能不会以相同的大小显示。

于 2013-09-06T16:30:32.153 回答
0

usingtry/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 总是在当前线程中调用。

于 2013-09-06T16:27:40.433 回答