In my MVC 3 C # application, I have some static object that I want to be available one request at a time. It can only be accessed using methods, but I want the lock to be maintained between calling its methods.
Calls will be made only in the controller, usually there will be one or two blocked blocks of code.
At first I wanted to expose some static public object and use it just as
lock(MyClass.lockObject) { MyClass.doStuff(); MyClass.doStuff2(); }
but I find him prone to errors, as I can forget to block him somewhere. I wonder if this is the correct way to use Monitor.Enter() in the constructor and Monitor.Exit() in the Dispose method, and then change my methods to non-static? Say something like:
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();
Then I could use it like:
using(MyClass myinstance = new MyClass()) { myInstance.doStuff(); myInstance.doStuff2(); }
Then, even if I forgot to wrap the code during use, it will still be blocked and there will be some chance that it will be unlocked during garbage collection ...
I donโt own C # and sometimes I donโt see some aspects, and threads will never be easy to debug later, so I wonder if I am well on a good track. Is this the right way to achieve my goal?
EDIT:
Extending the idea of โโMaster Morality, will this method be better (I simplified it a bit, since I only need one instance of the resource)?
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();