锁定并不prevent InvalidOperationException异常:对象是目前在其他地方使用 [英] Locking does not prevent InvalidOperationException: Object is currently in use elsewhere
问题描述
我是IM pression,根据锁()
将prevent多个线程同时访问一个对象。
I was under the impression that lock()
would prevent multiple threads from accessing an object simultaneously.
但是,一个InvalidOperationException(对象是目前在其他地方使用)仍然经常被以下code抛出:
But, an InvalidOperationException (Object is currently in use elsewhere) is still frequently thrown by the following code:
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);
}
需要注意以下几点:
Some things to note:
- 我分手了
的计算X
来的异常的原因隔离。它似乎来自访问该位图。 - 我尝试创建位图的本地副本,但这恰恰会导致相同的异常。我试过
克隆()
ING并创建一个新的位图。无论是作品。 - 我试着锁定在
这个
(如图)和位图对象。无论是作品。
- I split up the calculation of
x
to isolate the cause of the exception. It appears to come from accessing the bitmap. - I tried creating a local copy of the bitmap, but this just causes the same exception. I've tried
Clone()
ing and creating a new Bitmap. Neither works. - I've tried locking on
this
(as seen) and on the bitmap object. Neither works.
我是否尝试使用锁()
中的我不应该来的方法?难道我误解了它的目的是什么?我怎样才能prevent 出现InvalidOperationException
S'
Am I trying to use lock()
in a way I'm not supposed to? Have I misunderstood it's purpose? How can I prevent InvalidOperationException
s?
推荐答案
我最终得到了这条底线。我搬到了锁入位图属性的getter / setter方法,并尽快实现深层复制的方法来释放特性越好。
I eventually got to the bottom of this. I moved the locks into the getter / setter methods of the bitmap property and implemented a "deep copy" method to free up the property as soon as possible.
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);
}
}
这篇关于锁定并不prevent InvalidOperationException异常:对象是目前在其他地方使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!