2010-08-17 173 views
1

我在写C#应用程序,它将图片框屏幕保存为JPEG文件。C#Image:试图读取或写入受保护的内存

一个线程创建的图像:

IntPtr copyPtr = new IntPtr((void*)pArray); 
image = new Bitmap(bitmapInfo.biWidth, Math.Abs(bitmapInfo.biHeight), bitmapInfo.biWidth * 3, PixelFormat.Format24bppRgb, copyPtr); 
lock (image) 
{ 
    this.CreateGraphics().DrawImage(image, (window_width - (width * new_value))/2, (window_height - (height * new_value))/2, width * new_value, height * new_value); 
} 

与其它线程保存图片:

try 
{ 
     while ((t < (time * 60 * 1000)) && !done) 
     { 
      lock (image) 
      { 
      image.Save(folder + this.filename + DateTime.Now.ToString("yyyMMddHHmmssFFFFFFF") + ".jpg", ImageFormat.Jpeg); 
      } 
      t = t + interval; 
      System.Threading.Thread.Sleep(interval); 
      i++; 
     } 
} 
catch (Exception e) 
{ 
    Console.WriteLine("Exception: " + e.Message); 
    Console.WriteLine("Stack trace: " + e.StackTrace); 
} 

但有时我得到这个异常:

Exception: Attempted to read or write protected memory. This is often an indicat 
ion that other memory is corrupt. 
Stack trace: at System.Drawing.SafeNativeMethods.Gdip.GdipSaveImageToFile(Han 
dleRef image, String filename, Guid& classId, HandleRef encoderParams) 
    at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, Encoder 
Parameters encoderParams) 
    at System.Drawing.Image.Save(String filename, ImageFormat format) 
    at MyDLL.Window.SaveJPEG(String filename, Int32 fps, Int32 
time) 

我用锁呼叫,但它似乎不是很有帮助。我可以将图像保存在同一个线程中。但也许有任何解决方案如何在使用线程时解决这个问题。谢谢。

回答

2

检查您的image变量的声明。 您可能已将其定义为公开访问。 通常最好只在代码中定义一个私有或本地对象,然后锁定例如

Object imageLock = new Object(); 
IntPtr copyPtr = new IntPtr((void*)pArray); 
image = new Bitmap(bitmapInfo.biWidth, Math.Abs(bitmapInfo.biHeight), bitmapInfo.biWidth * 3, PixelFormat.Format24bppRgb, copyPtr); 
lock (imageLock) 
{ 
    this.CreateGraphics().DrawImage(image, (window_width - (width * new_value))/2, (window_height - (height * new_value))/2, width * new_value, height * new_value); 
} 

,然后在另一个线程代码:

Object imageLock = new Object(); 
try 
{ 
     while ((t < (time * 60 * 1000)) && !done) 
     { 
      lock (imageLock) 
      { 
      image.Save(folder + this.filename + DateTime.Now.ToString("yyyMMddHHmmssFFFFFFF") + ".jpg", ImageFormat.Jpeg); 
      } 
      t = t + interval; 
      System.Threading.Thread.Sleep(interval); 
      i++; 
     } 
} 
catch (Exception e) 
{ 
    Console.WriteLine("Exception: " + e.Message); 
    Console.WriteLine("Stack trace: " + e.StackTrace); 
} 
+0

谢谢,我检查了我定义的图像公共访问 – kesrut 2010-08-17 12:24:04

0

既然你在第一线中每次创建一个新的形象,它不会是相同的对象,第二线程锁定。

1

根据documentation您应该定义一个专用对象用作锁对象。这条线具体为:

一般情况下,避免锁定在一个公共类型,或者超出你的代码的控制情况

即:

object lockObject = new object(); 
IntPtr copyPtr = new IntPtr((void*)pArray); 
image = new Bitmap(bitmapInfo.biWidth, Math.Abs(bitmapInfo.biHeight), bitmapInfo.biWidth * 3, PixelFormat.Format24bppRgb, copyPtr); 
lock (lockObject) 
{ 
    this.CreateGraphics().DrawImage(image, (window_width - (width * new_value))/2, (window_height - (height * new_value))/2, width * new_value, height * new_value); 
} 
相关问题