我的印象是lock()
会阻止多个线程同时访问对象。
但是,以下代码仍然经常引发InvalidOperationException(Object目前正在其他地方使用):
lock (this)
{
localCopy = (Bitmap)this.bm.Clone();
int x, y;
float pX = this.p.x;
int width = localCopy.Width;
x = (int)Math.Round((double)(pX * (float)width));
if (x >= localCopy.Width) x = localCopy.Width - 1;
y = (int)Math.Round((double)(this.p.y * (float)localCopy.Height));
if (y >= localCopy.Height) y = localCopy.Height - 1;
colourPixel = localCopy.GetPixel(x, y);
}
有些注意事项:
x
的计算分开以隔离异常的原因。它似乎来自访问位图。Clone()
并创建一个新的Bitmap。两者都不起作用。this
(如图所示)和位图对象。两者都不起作用。我是否尝试以某种我不应该使用的方式使用lock()
?我误解了它的目的吗?如何阻止InvalidOperationException
?
答案 0 :(得分:3)
可能尝试使用对象锁定目的而不是锁定“this”。
班级变量
private static object syncRoot = new Object();
以及何时使用
lock (syncRoot)
{
....
}
答案 1 :(得分:1)
我最终走到了最底层。我将锁移动到位图属性的getter / setter方法中,并实现了“深层复制”方法,以尽快释放属性。
private static object syncRoot = new Object();
private Bitmap _bm;
private Bitmap bm
{
get
{
lock (syncRoot)
return this._bm.DeepClone();
}
set
{
lock (syncRoot)
{
this._bm = value.DeepClone();
}
}
}
DeepClone()扩展方法来自an answer to another question:
public static T DeepClone<T>(this T a)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, a);
stream.Position = 0;
return (T)formatter.Deserialize(stream);
}
}