2010-08-17 175 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); 
} 
相關問題