通用GDI +错误:调用GC.Collect()时避免使用

|| 我有这段代码(\“ ruta1 \”和\“ ruta2 \”是包含不同图像路径的字符串):
   Bitmap pic;
   Bitmap b = new Bitmap(SomeWidth, SomeHeight);
   g = Graphics.FromImage(b);
   g.FillRectangle(new SolidBrush(Color.White), 0, 0, b.Width, b.Height);

   b.Save(ruta2, ImageFormat.Jpeg);
   g.Dispose();
   b.Dispose();

   b = new Bitmap(OtherWidth, OtherHeight);
   pic = new Bitmap(ruta2);
   g = Graphics.FromImage(b);
   g.FillRectangle(new SolidBrush(Color.White), 0, 0, b.Width, b.Height);
   g.DrawImage(pic, 0, 0, pic.Height, pic.Width); 

   pic.Dispose();
   b.Save(ruta2, ImageFormat.Jpeg);
   g.Dispose();
   b.Dispose();

   pic = new Bitmap(ruta1);
   b = new Bitmap(AnotherWidth, AnotherHeight);
   g = Graphics.FromImage(b);
   g.FillRectangle(new SolidBrush(Color.White), 0, 0, b.Width, b.Height);

   int k = 1;

   // I just draw the \"pic\" in a pattern on \"b\"
   for (h = 0; h <= b.Height; h += pic.Height)
       for (w = 0; w <= b.Width; w += pic.Width)
            g.DrawImage(pic, w, h, k * pic.Width, k * pic.Height);

   pic.Dispose();            
   GC.Collect();  // If I comment this line, I get a \"generic GDI+ Error\" Exception
   b.Save(ruta1, ImageFormat.Jpeg);
   g.Dispose();
   b.Dispose();
处置后是否将pic = null设置无关紧要,如果不调用垃圾收集器,则会收到“ Generic GDI + Error \”异常。只有当我调用垃圾收集器时,我的程序才能正常运行。 有人可以解释这种行为吗?它是否取决于.Net框架版本? 我正在使用带有.Net Framework 3.5的Visual C#Express 2008     
已邀请:
首先,如果您使用\“
using
\”关键字来限定一次性对象(例如
Bitmap
Graphics
)的使用范围,而不是分别手动调用
Dispose()
,那将是很好的选择。使用“
using
”比较好,原因有很多,例如在引发异常时清理东西,但这也大大提高了代码的可读性。 其次,GDI画笔也是“ 6”个对象,因此您不应创建并忘记它们。而是这样做:
using (var brush = new SolidBrush(Color.White))
{
    g.FillRectangle(brush, 0, 0, width, height)
}
...或者更好的方法是,在应用程序的开始处创建画笔,并一直挂到最后(但不要忘记也要丢弃它们)。如果频繁进行,IIRC创建/处理画笔会极大地影响性能。 第三,我相信您的错误在第二部分: 您打开图像“ ruta2” 您创建一个新图像 您在该新图像中绘制\“ ruta2 \”的内容 您将新内容保存在\“ ruta2 \”文件的顶部,但是第1步中的原始图像仍处于加载状态,并且可能在\“ ruta2 \”文件中具有某些句柄,因此您需要先处置它覆盖文件。 如果您像这样重构第二部分,它应该可以工作:
using (var b = new Bitmap(OtherWidth, OtherHeight))
using (var g = Graphics.FromImage(b))
{
     using (var brush = new SolidBrush(Color.Red))
     {
         g.FillRectangle(brush, 0, 0, b.Width, b.Height);
     }
     using (var pic = new Bitmap(ruta2))
     {
         g.DrawImage(pic, 0, 0, pic.Height, pic.Width);
     }
     b.Save(ruta2, ImageFormat.Jpeg);
 }
    

要回复问题请先登录注册