在我的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