Я всегда использую отдельную переменную для соединений:
object syncObj = new object();
void Foo()
{
lock(syncObj)
{
// do some stuff
}
}
Соединяющиеся типы значения не имеют смысла так или иначе, потому что типы значения неизменны и не могут быть изменены. Соединение 'этого' также проблематично, потому что 'это' видимо к внешнему миру.
Для некоторой информации о том, как Монитор был первоначально предназначен, чтобы использоваться, см. Монитор (синхронизация)
Вы всегда можете вызвать статический метод TryEnter
в классе Monitor
, используя значение 0 в качестве значения для ожидания . Если он заблокирован, вызов вернет false.
Однако проблема здесь в том, что вам нужно убедиться, что список, к которому вы пытаетесь синхронизировать доступ, заблокирован сам по себе, чтобы синхронизировать доступ.
Обычно плохая практика - использовать объект, доступ к которому синхронизируется, в качестве объекта для блокировки (выставляя слишком много внутренних деталей объекта).
Помните, что блокировка может быть на любом другом, поэтому просто вызовите это в этом списке бессмысленно, если вы не уверены, что именно этот список заблокирован.
Monitor.TryEnter
завершится успешно, если объект не заблокирован, и вернет false, если в этот самый момент объект заблокирован. Однако обратите внимание, что здесь есть неявная гонка: экземпляр, возвращаемый этим методом, объект больше не может быть заблокирован.
В настоящее время вы можете вызвать Monitor.TryEnter, чтобы проверить, заблокирован ли объект или нет.
В .NET 4.0 команда CLR собирается добавить «API проверки блокировки»
Вот цитата из статьи Рика Байерса :
проверка блокировок
Мы добавляем несколько простых API-интерфейсов в ICorDebug, которые позволяют вам исследовать управляемые блокировки (мониторы). Например, если поток заблокирован в ожидании блокировки, вы можете узнать, какой другой поток в настоящее время удерживает блокировку (и если есть тайм-аут).
Таким образом, с помощью этого API вы сможете проверить:
1) Какой объект удерживает замок?
2) Кто его ждет?
Надеюсь, это поможет.
Я не уверен, что статический вызов TryEnter с временем 0 гарантирует, что блокировка не будет получена, если она доступна. Решение, которое я сделал для проверки в режиме отладки, что переменная sync заблокирована, было следующим:
#if DEBUG
// Make sure we're inside a lock of the SyncRoot by trying to lock it.
// If we're able to lock it, that means that it wasn't locked in the first
// place. Afterwards, we release the lock if we had obtained it.
bool acquired = false;
try
{
acquired = Monitor.TryEnter(SyncRoot);
}
finally
{
if (acquired)
{
Monitor.Exit(SyncRoot);
}
}
Debug.Assert(acquired == false, "The SyncRoot is not locked.");
#endif