我正在编写C#应用程序,它将图片框屏幕保存为JPEG文件。
创建图像的一个线程:
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)
我使用了锁定电话,但似乎没有用。我可以在同一个线程中保存图像。但也许有任何解决方案如何在使用线程时解决这个问题。感谢。
答案 0 :(得分: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);
}
答案 1 :(得分: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);
}
答案 2 :(得分:0)
由于您每次都在第一个线程中创建一个新图像,因此它不会与第二个线程锁定的对象相同。