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.

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
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
Jamie Kurtz
huh
two lines of code. . .
lock(syncroot)
{
theDelegate = MyFunc;
. . . do stuff here
theDelegate = null;
}
where is the tendency for an error
March3rd
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.