Весь код, который происходит в блоке SyncLock
, синхронизируется со всем другим кодом, происходящим в блоке SyncLock
того же объекта . Очевидно, Me
- это не то же самое, что syncRoot
(то есть, я предполагаю, Me.SyncRoot
, если ваш Me
- ICollection
).
Код в блоке SyncLock
одного объекта не будет синхронизироваться с кодом в блоке SyncLock
другого объекта.
Скажем, у вас есть этот код:
' happening on thread 1 '
SyncLock myColl.SyncRoot
myColl.Add(myObject)
End SyncLock
' happening on thread 2 '
SyncLock myColl.SyncRoot
myColl.Remove(myObject)
End SyncLock
С вышеизложенным все в порядке: вызовы Add
и Remove
синхронизированы, что означает, что они не будут выполняться одновременно (в зависимости от того, какой вызов будет вызван первым, будет выполнен, а второй не будет выполнен, пока не завершится первый).
Но предположим, что вместо этого у вас было:
' happening on thread 1 '
SyncLock myColl.SyncRoot
myColl.Add(myObject)
End SyncLock
' happening on thread 2 '
SyncLock myColl ' NOTE: SyncLock on a different object '
myColl.Remove(myObject)
End SyncLock
Вышеуказанные вызовы Add
и Remove
не синхронизируются любым способом, формой или формой. Таким образом, в приведенном выше коде нет безопасности потока.
Теперь, почему существует SyncRoot
? Проще говоря, потому что имеет смысл синхронизировать в наименьшем необходимом масштабе ; т.е. нет необходимости синхронизировать код, который на самом деле не нужно синхронизировать.
Рассмотрим этот пример:
' happening on thread 1 '
SyncLock myColl
myColl.Add(myObject)
End SyncLock
' happening on thread 2 '
SyncLock myColl
' Why you would have code like this, I do not know; '
' this is just for illustration. '
myColl.Name = myColl.Name.Replace("Joe", "Bill")
End SyncLock
' happening on thread 3 '
SyncLock myColl
myColl.Name = myColl.Name.Replace("Bill", "Joe")
End SyncLock
В приведенном выше примере вы синхронизируете больше, чем необходимо . Вызов Add
на самом деле не имеет ничего общего с переименованием объекта myColl
; таким образом, код не нужно синхронизировать.
Это идея, лежащая в основе свойства SyncRoot
: оно дает вам объект, цель которого состоит в том, чтобы предоставить общий объект, с которым можно синхронизировать изменения / перечисления коллекции. Код, который включает коллекцию некоторым другим способом - но который не нужно синхронизировать с кодом, который изменяет или читает содержимое коллекции - должен быть синхронизирован, где это необходимо , на другом объекте.