In my unsafe class below, what can be done to prevent someone from executing the unsafe method without first obtaining the lock?
class Unsafe
{
private static readonly object lockObj;
void MethodA()
{
lock (lockObj)
{
// do some things
DoUnsafeThing();
}
}
void MethodB()
{
lock (lockObj)
{
// do some things
DoUnsafeThing();
}
}
void DoUnsafeThing()
{
if (callerHasLock)
// Do the unsafe thing
else
return; // or throw some exception
}
}
Obtaining the lock again inside DoUnsafeThing()
is an option:
void DoUnsafeThing()
{
lock (lockObj)
{
// Do the unsafe thing
}
}
But DoUnsafeThing()
can now be called by threads that don't already possess the lock.
You should be able to use Monitor.IsEntered() to verify that the thread itself has already obtained the lock:
void DoUnsafeThing()
{
if (Monitor.IsEntered(lockObj))
// Do the unsafe thing
else
return; // or throw some exception
}
You can use the Monitor
class to work with locks. In C#, the lock(...)
statement is just syntactic sugar for Monitor.Enter(o); try {...} finally {Monitor.Exit(o);}
Monitor.Enter(o); try {...} finally {Monitor.Exit(o);}
. There are other options within it for fine-tuning. Remember, multi-threading is Hard. Know your toolset.
EDIT: (in response to framework version question update)
Prior to .NET 4.5, AFAIK the only way to handle this would be to use a thread-static Boolean alongside the synchronization object, set to true
just after entering and false
just before exiting. That same Boolean--call it callerHasLock
, to conform with your code above--can then be tested within the lock context with the same result as Monitor.IsEntered
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.