How do I check if object locked?

Is there a way to access the list of locked objects kept by System.Threading.Monitor

The purpose being, I have a function that I only want called if the sync object in the class is in a locked state.  If the sync object is not locked, I want the function to throw an error, but how do I check if the sync object is locked

Thanks.


Answer this question

How do I check if object locked?

  • Pradeepkonda

    lock(syncroot)
    {     
         theDelegate = MyFunc;
         
         . . .  do stuff here
         
         theDelegate = null;
         
    }

     

    Dangerous: if "do stuff here" throws an exception, theDelegate won't be set to null.


  • passaad

    and why wouldnt the abstract be available to him please explain that to me.

    geez. . . dont make me write a program for you. if he needs another method, the maintenence programmer just adds a new class.

    public class LockingDifferentObject: LockingObjectBase
    {
            protected override void TheMethod()
            {
                   for (int i = 0; i < 1000000000; i++)
                                      Console.WriteLine(1000000000- i);
            }
    }

    and then to use

    LockingDifferentObject other = new LockingDifferentObject(someOtherLockedOnlyMethod);
             
    and usage is still the same:

    other.ObjectLockedMethod();



  • Splinta

    > the maintenance programmer doesnt even have to think about it

    When the maintenance programmer adds a new method TheOtherMethod which also needs to use the same lock, he will need to modify the abstract base class to add a protected abstract TheOtherMethod and a public OtherThreadedMethod, and will have to implement the pattern in OtherThreadedMethod.

    Also it will not always be possible to use an abstract base class - the class in question may already have a base class.

     

     


  • Youenn Trebossen

    If I needed to be able to test if a lock was being held by another thread I would use one of the other synchronization classes in the System.Threading namespace instead of the C# lock statement (Monitor, Mutex, ReaderWriterLock depending on the cirumstances).

    I think this would give a more elegant solution.  The delegate solution requires every user of the lock statement to implement a non-standard pattern, and will be broken the first time a maintenance programmer forgets to do it.

     


  • kowgli

    and the maintenence programmer should not have the code to LockingObjectBase available to him, that should be frozen. all he should have is the dll. and thinking about it, ObjectLockedMethod shouldnt be a public delegate but a full fledged method -

    Am I going to have to explain how to use parameters for ObjectLockedMethod

    Add a LockedMethodArgs class.

    public abstract class LockingObjectBase
    {
            object _syncRoot;
            LockMethodDelegate _delegateHolder;
            static LockingObject(){ _syncroot = new object();}
            delegate void LockMethodDelegate(LockMethodArgs args)
            public void ObjectLockedMethod(LockMethodArgs args)
            {
                    if (_delegateHolder == null)
                      throw new UnlockedObjectException("Object Not Locked")
                  _delegateHolder(args);
            }

            public LockingObject(LockMethodDelegate aMethod)
            {
                    _delegateHolder = theMethod;
            }
            protected abstract void TheMethod();
            public void ThreadedMethod()
            {
                      lock(_syncRoot)
                      {
                             ObjectLockedMethod= _delegateHolder;        
                              try
                             {
                                     TheMethod();
                             }
                             finally
                             {
                                  ObjectLockedMethod = null;
                             }

                      }
            }        
    }

    public class LockMethodArgs        
    {                
        public static Empty
        {                
             get {return null;}              
        }        
    }

     



  • Sonnemaf

    It's a little too hackish of a solution for me.  lock() {} is very nice in that throws and returns unlock the resource automatically.  Using the solution above I would have to add many lines to turn the delegate back to null, etc.. which in itself increases my chance for coding error and not remembering later on the custom conventions I used everytime I locked.

    If it's just not possible please let me know because that's a good enough answer for me. I was just wondering if there was something out there like

    bool System.Threading.Monitor.IsLocked(object)

    Thanks.

  • Muhammad Subhan

    yeah. . . no sh|t. . . wasnt meant as a robust solution. . . with a little creativity on can see how the pattern could be applied in an extremely elegant fashion.

    look at my followup



  • wgaspk

    use a delegate. . . in the firstline after aquiring the lock, set the delegate to the method you want to call. in the last line before releaseing the lock set the delegate to null.

    calling the delegate from anywhere in the program will throw an error if the sync object isn't locked.



  • cwilliam

    This is an example implementing the solution above some access members need to be changed but this is the general gist of it.

    byte[] RandomFunction()
    {
         lock( LockingObject._syncRoot )
         {
              LockingObject.ObjectLockedMethod = LockingObject.LockedMethod;       

              LockingObject.Write();
              LockingObject.Write();

              if( LockingObject.WriteSpecial() == false)
              {
                   LockingObject.ObjectLockedMethod = null;     
                   return null;
              }          
                
              byte[] data = LockingObject.FinishWrite();
              LockingObject.ObjectLockedMethod = null;     
              return data;
         }
    }

    The internal functions like Write and FinishWrite would check and make sure ObjectLockedMethod is not null to know that the class is locked. This solution does work like I said before.  The problem is remembering to reset ObjectLockedMethod back to null before exiting the lock.  And in the situation LockingObject.Write() threw an exception with me forgetting to catch it like in the example above, ObjectLockedMethod would never be set back to null.

    In my code there are about 50 different RandomFunctions() like this one, so the overhead and chance to mess something up is high. All would be averted though if somehow inside Write() and FinishWrite() I could check if the _syncRoot object is locked.


  • Patrick Roberts

    and if you use the abstract class pattern, the maintenance programmer doesnt even have to think about it

  • Jamie Kurtz

    huh

    two lines of code. . .

    lock(syncroot)
    {     
         theDelegate = MyFunc;
         
         . . .  do stuff here
         
         theDelegate = null;
         
    }

    where is the tendency for an error
         

                       

                       

     

     



  • March3rd

    typos in my above example fixed

  • dcallaghan

    public class LockingObject
    {
            object _syncRoot;
            static LockingObject(){ _syncroot = new object();}
            delegate void LockMethodDelegate()
            private void LockedMethod(){ Console.WriteLine("Object Locked";);}
            public static LockMethodDelegate ObjectLockedMethod;

            public void ThreadedMethod()
            {
                      lock(_syncRoot)
                      {
                              ObjectLockedMethod= LockedMethod;        
                              for (int i = 0; i < 1000000000; i++)
                                      Console.WriteLine(i);
                              ObjectLockedMethod = null;        
                      }
            }        
    }

    call via        
     LockingObject.ObjectLockedMethod();

    if _syncroot isnt locked, a null reference exception is thrown

    or you can simply test

    if ( LockingObject.ObjectLockedMethod == null)         
          throw new MyCustomObjectUnlockedException("Object not locked");
    else 
          LockingObject.ObjectLockedMethod()

     

     

           


           

     



  • Yitzhak Khabinsky

    ahhh. . . but here this calls for an abstract class and now, the constructor takes a delegate of the method that is to be called and the delegate isnt static

     so. . . just inherit from LockingObjectBase and override TheMethod for each of your functions. And if you do it this way, your code will be quite clear and easy to read.

    public abstract class LockingObjectBase
    {
            object _syncRoot;
            LockMethodDelegate _delegateHolder;
            static LockingObject(){ _syncroot = new object();}
            delegate void LockMethodDelegate()
            public LockMethodDelegate ObjectLockedMethod;

            public LockingObject(LockMethodDelegate aMethod)
            {
                    _delegateHolder = theMethod;
            }
            protected abstract void TheMethod();
            public void ThreadedMethod()
            {
                      lock(_syncRoot)
                      {
                             ObjectLockedMethod= _delegateHolder;        
                              try
                             {
                                     TheMethod();
                             }
                             finally
                             {
                                  ObjectLockedMethod = null;
                             }

                      }
            }        
    }

    A concrete instance

    public class LockingCountingObject: LockingObjectBase
    {
            protected override void TheMethod()
            {
                   for (int i = 0; i < 1000000000; i++)
                                      Console.WriteLine(i);
            }
    }

    the class with the function you only want to execute if the other object is locked

    public class CounterInitializer
    {
            protected void TheLockedMethod()
            {
               Console.WriteLine("Object Locked");
            }

            public  void InitializeTheLockedMethod(out LockingCountingObject obj)
            {
                   obj = new LockingCountingObject(TheLockedMethod);
            }
    }        

    and then elsewhere in your code where you have a CounterInitializer, countInit:

    LockingCountingObject lo = null;
    countInit.InitializeTheLockedMethod(out lo);

    and then elsewhere you can do  

    lo.ObjectLockedMethod();

    and it will throw the error if not locked.

     



  • How do I check if object locked?