2

lock()複数のスレッドがオブジェクトに同時にアクセスするのを防ぐという印象を受けました。

ただし、InvalidOperationException (オブジェクトは現在別の場所で使用されています) は、次のコードによって依然として頻繁にスローされます。

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()新しいビットマップを作成して作成しようとしました。どちらも機能しません。
  • 私はthis(見たように)とビットマップオブジェクトをロックしようとしました。どちらも機能しません。

lock()想定されていない方法で使用しようとしていますか? その目的を誤解していますか?どうすればInvalidOperationExceptionsを防ぐことができますか?

4

2 に答える 2

4

おそらく、「これ」をロックするのではなく、ロック目的でオブジェクトを使用してみてください。

クラスレベル変数

private static object syncRoot = new Object();

そして、あなたが使用しているとき

lock (syncRoot)
{
....
}
于 2012-10-03T13:47:16.827 に答える
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()拡張メソッドは、別の質問への回答から削除されました。

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);
    }
}
于 2012-10-05T13:08:56.920 に答える