我正在使用一个通过多个线程调用主函数的 API。我试图通过该函数访问另一个类中的位图并从中写入,但即使将其设置为使用完全不同的对象实例后,我也遇到了 InvalidOperationException:位图区域已被锁定。
我尝试在主函数和调用 Bitmap.LockBits(...) 的位置锁定代码。是的,当我完成后,UnlockBits 就会被调用。
/* Part of Class B */
public Surface imageSurface //Surface is a field of pixels, more or less.
{
get
{
if (_CurrImage != null && _imageSurface == null)
{
_imageSurface = Surface.CopyFromBitmap(_CurrImage);
return Surface.CopyFromBitmap(_imageSurface.CreateAliasedBitmap());
}
else
{
Surface clearPixel = new Surface(1, 1);
clearPixel[0, 0] = ColorBgra.FromBgra(255, 255, 255, 0);
return clearPixel;
}
}
}
/* the "main" function, Class A */
public override void Render(ClassBPrototype parameters, ...)
{
ClassB token = (ClassB)parameters; // Here we go again~!
...
Surface ourSurface = dstArgs.Surface;
if (token.imageSurface.Size != null)
{
ourSurface = token.imageSurface;
}
lock(typeof(ClassA))
{
for (int lRectangleIndex = ...)
{
Rectangle lRectangle = rois[lRectangleIndex];
for (int y = ...)
{
surfaceY = (ourSurface.Height / 2) - (y - (int)CenterY);
for (int x = ...)
{
surfaceX = (ourSurface.Width / 2) - (x - (int)CenterX);
if (surfaceX >= 0 && surfaceX < ourSurface.Width && surfaceY >= 0 && surfaceY < ourSurface.Height)
{
dstArgs.Surface[x, y] = ourSurface[surfaceX, surfaceY];
}
else
{
dstArgs.Surface[x, y] = ColorBgra.FromBgra(255, 255, 255, 0);
}
}
}
}
}
}
问题很可能是共享资源(位图)不受代码示例中的锁保护。锁需要包裹两个LockBits
and UnlockBits
呼吁有效防止同时访问Bitmap
实例。
在这种情况下,我建议使用实际的Bitmap
实例作为锁对象,因为这是需要防止来自不同线程的同时访问的对象。
锁定typeof(ClassA)
仅建议在静态方法内使用锁时。
请注意,锁是互斥锁,当一个线程获得锁时,其他线程将被挂起。如果大部分时间都花在锁内,则多线程不会带来或很少有并行化的好处。
如果发生异常,锁将根据锁构造的设计被释放,而UnlockBits
方法通常不会被调用。如果可以抛出并捕获异常,我建议调用UnlockBits
来自finally 块的方法。像这样的事情:
private Bitmap _bitmap;
public void foo()
{
lock (_bitmap)
{
BitmapData data;
try
{
data = _bitmap.LockBits(area, ImageLockMOde.ReadOnly, pixelFormat);
UseBitmapData(data);
}
finally
{
_bitmap.UnlockBits(data);
}
}
}
该逻辑也可以封装在它自己的类中,实现 IDisposable 接口,从而实现强大的功能using
要使用的构造。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)