锁定不会阻止InvalidOperationException:Object当前正在其他地方使用

时间:2012-10-03 13:13:17

标签: c# bitmap locking invalidoperationexception

我的印象是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

2 个答案:

答案 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);
    }
}