The question here is: If a thread that acquiring an exclusive lock to an object –for instance by using Monitor.Enter– is terminated, does that magically frees the exclusive lock on that object? if that is true, then suppose we call Monitor.Exit from another thread –because we assumed that object is locked–, isn’t that will throw exeption of type SynchronizationLockException?
I am not sure it this is the expected behavior or a bug…
To demonstrate the issue, I have created a simple piece of code that calls Monitor.TryEnter without calling Monitor.Exit at System.Timers.Timer.Elapsed event callback “Note that the Timers.Timer class uses internally ThreadPool to run the callback event handler, and it may calls the elapsed callback each time on a different thread from the pool..”
class Foo
{
private System.Timers.Timer _timer = new System.Timers.Timer(2000);//every 2s
private static readonly object _locker = new object();//static locker object
public Foo()
{
_timer.Elapsed += delegate
{
if (Monitor.TryEnter(_locker))//acquiring the lock without calling Exit..
{
Console.WriteLine(string.Format("Access Succeed!!, Thread Id {0}",
Thread.CurrentThread.ManagedThreadId));
Thread.Sleep(6000);//simulate a work for 6 seconds
}
else
{
Console.WriteLine(string.Format("Unable to access to locker method within locker object, Thread Id {0}",
Thread.CurrentThread.ManagedThreadId));
}
};
_timer.Start();
}
}
//to test: just initialize a new instance of foo class
Foo foo = new Foo();
//blocks until application is terminated..
Thread.Sleep(Timeout.Infinite);
Results at output window shows:
Access Succeed!!, Thread Id 11
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
Access Succeed!!, Thread Id 11
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
Access Succeed!!, Thread Id 11
Unable to access to locker method within locker object, Thread Id 12
Unable to access to locker method within locker object, Thread Id 12
....
No threads are being terminated here.
Rather, they’re returned to the threadpool, only to be reused by later timer events.
Monitor.Enteris re-entrant; entering a lock twice on the same thread will not block.