在我的 MVC 3 C# 应用程序中,我有一些静态对象,我希望一次可用于一个请求。只能通过方法访问它,但我希望在调用其方法之间保持锁定。
调用只会在控制器中完成,通常会有一两个锁定的代码块。
起初我想公开一些静态公共对象并像使用它一样简单地使用它
lock(MyClass.lockObject)
{
MyClass.doStuff();
MyClass.doStuff2();
}
,但我发现它容易出错,因为我可能忘记将它锁定在某个地方。我想知道Monitor.Enter()
在构造函数和Monitor.Exit()
Dispose 方法中使用它是否是正确的方法,然后将我的方法更改为非静态方法?说,类似:
public class MyClass:IDisposable
{
static protected object _locker = new object();
protected bool isDisposed = false;
public MyClass()
{
Monitor.Enter(_locker);
}
public void Dispose()
{
if (!isDisposed)
{
Monitor.Exit(_locker);
GC.SuppressFinalize(this);
isDisposed = true;
}
}
~SPInstances()
{
Dispose();
}
public void doStuff()
{
if(isDisposed) throw new ObjectDisposedException();
// do stuff here, etc.
}
}
然后我可以将其用作:
using(MyClass myinstance = new MyClass())
{
myInstance.doStuff();
myInstance.doStuff2();
}
然后,即使我在使用时忘记包装代码,它仍然会锁定,并且在垃圾收集期间它有可能会被解锁......
我不精通C#,有时会忽略某些方面,并且线程以后调试起来也不容易,所以我想知道我是否走上了正轨。这是实现我的目标的正确方法吗?
编辑:
扩展Master Morality的想法,这种方式会更好(我简化了一点,因为我只需要一个资源实例)?
public class MyClass
{
static protected readonly MyResourceType _myResourceStatic = new MyResourceType();
static public void DoWork(Action<MyClass> action)
{
lock(_myResource)
{
action(new MyClass(_myResource));
}
}
protected MyClass(MyResourceType myResource)
{
_myResource = myResource;
}
protected readonly _myResource;
public void DoFirstThing() { ... }
public void DoSecondThing(){ ... }
}
MyClass.DoWork(x =>
{
x.DoFirstThing();
// do unrelated stuff
x.DoSecondThing();
});