我收到此错误,看起来是因为不同线程正在访问同一个 Bitmap 对象。但是我到处都在使用锁。
public class MySingleInstanceClass
{
private Object locker = new Object();
private Bitmap myImage = new Bitmap(100, 100);
public Bitmap MyImage
{
get
{
lock (locker)
return myImage;
}
private set
{
lock (locker)
myImage = value;
}
}
private void Refresh()
{
lock (locker)
{
var g = Graphics.FromImage(myImage);
// do more processing
}
}
}
Class MySingleInstanceClass
将只有一个实例。对 MyImage
和 Refresh()
的调用可能来自不同的线程。据我了解, lock(locker)
中的代码只有在另一个线程中完成后才会执行,但我仍然遇到错误。谁能指出代码中的缺陷?
异常看起来像这样:
A first chance exception of type 'System.InvalidOperationException' occurred in System.Drawing.dll
Error: Object is currently in use elsewhere.
at System.Drawing.Graphics.FromImage(Image image)
at (points to the line containing var g = Graphics.FromImage(myImage);)
最佳答案
locker
对象不是静态的;因此每个新实例都会创建自己的储物柜;如果使用多个对象,您需要将 locker
创建为静态,以防止其他线程访问。
private static Object locker = new Object();
对于单对象场景,使用非静态类级别变量作为储物柜是合适的。如果你在使用这种场景,我觉得单例的实现有一些问题。
更新:
public sealed class MySingleInstanceClass
{
private static volatile MySingleInstanceClass instance;
private static object syncRoot = new Object();
private Bitmap myImage;
private MySingleInstanceClass()
{
myImage = new Bitmap(100, 100);
}
public static MySingleInstanceClass Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new MySingleInstanceClass();
}
}
return instance;
}
}
public Bitmap MyImage
{
get
{
lock (syncRoot)
return myImage;
}
private set
{
lock (syncRoot)
myImage = value;
}
}
public void Refresh()
{
lock (syncRoot)
{
var g = Graphics.FromImage(myImage);
// do more processing
}
}
}
关于c# - 对象当前正在别处使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14660815/