在我的MVC 3 C#应用程序中,我有一个静态对象,我希望一次对一个请求可用。只有通过方法才能访问它,但是我希望锁定在调用其方法之间。什么是锁定线程的正确方法?
调用只能在控制器中完成,通常会有一个或两个锁定的代码块。
起初我想揭露一些静态公共对象,并用它只是像
lock(MyClass.lockObject)
{
MyClass.doStuff();
MyClass.doStuff2();
}
,但我觉得它容易出错,因为我可能会忘了某处将其锁定。我想知道在一个Dispose方法中使用Monitor.Enter()
和Monitor.Exit()
是否合适,然后将我的方法更改为非静态?我说,是这样的:
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#,有时会忽略某些方面,而线程从来不容易调试,所以我想知道我是否在一个好的轨道上。这是实现我的目标的正确方法吗?
编辑:
扩展硕士道德观念,将这种方式是更好的(我简化了一点,因为我只需要一个资源的情况下)?
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();
});
“但我想上保持全锁请求“ - 不会导致您的站点只能一次处理一个请求(至少有一个请求一次访问此静态对象)? – mbeckish 2012-08-02 14:23:14
对不起,这太夸张了;我的意思是我希望它在方法调用之间锁定,较长的请求将在开始时和最终处理时锁定 – trakos 2012-08-02 14:28:48
更准确地说明范围。我不确定你有保证所有相关的代码(Controller,View,ActionFilters)都能在同一个线程上运行。 – 2012-08-02 14:34:18