問題描述
我的印象是 lock()
會阻止多個線程同時訪問一個對象.
I was under the impression that lock()
would prevent multiple threads from accessing an object simultaneously.
但是,以下代碼仍然經(jīng)常拋出 InvalidOperationException(對象當(dāng)前正在其他地方使用):
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);
}
注意事項:
- 我拆分了
x
的計算來隔離異常的原因.它似乎來自訪問位圖. - 我嘗試創(chuàng)建位圖的本地副本,但這只會導(dǎo)致相同的異常.我試過
Clone()
ing 并創(chuàng)建一個新的位圖.兩者都不起作用. - 我嘗試鎖定
this
(如所見)和位圖對象.兩者都不起作用.
- 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.
我是否試圖以一種不應(yīng)該的方式使用 lock()
?我誤解了它的目的嗎?如何防止 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方法中,并實現(xiàn)了一個深拷貝"的方法來盡快釋放這個屬性.
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() 擴展方法來自另一個問題的答案:
The DeepClone() extension method was cribbed from 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);
}
}
這篇關(guān)于鎖定不會阻止 InvalidOperationException:對象當(dāng)前正在其他地方使用的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!