Вопрос здесь следующий: если поток, который получает монопольную блокировку для объекта - например, с помощью Monitor.Enter
, - прерывается, освобождает ли это волшебным образом монопольную блокировку для этого объекта?если это правда, то предположим, что мы вызываем Monitor.Exit
из другого потока - потому что мы предполагали, что объект заблокирован - разве это не выбросит исключение типа SynchronizationLockException
?
Я неуверен, что это ожидаемое поведение или ошибка ...
Чтобы продемонстрировать проблему, я создал простой фрагмент кода, который вызывает Monitor.TryEnter без вызова Monitor.Exit
at System.Timers.Timer.Elapsed обратный вызов события "Обратите внимание, что класс Timers.Timer внутренне использует ThreadPool
для запуска обработчика события обратного вызова, и он may каждый раз вызывает прошедший обратный вызов в другом потоке из пула .. "
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);
Результаты в окне вывода показывают:
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
....