Зачем блокировать Collection.SyncRoot, а не просто блокировать коллекцию? - PullRequest
6 голосов
/ 29 июня 2011

Я пытаюсь понять смысл syncroot в ICollection. Почему бы просто не заблокировать коллекцию?

lock(myCollection)
{
    //do stuff to myCollection
}

против

lock(myCollection.SyncRoot)
{
    //do stuff to myCollection
}

Ответы [ 2 ]

8 голосов
/ 29 июня 2011

Обычно, если безопасность потока является серьезной проблемой, я бы избегал любой из этих опций.

Гораздо лучшим вариантом, как правило, является сохранение вашей собственной закрытой переменной и блокировка ее во всех методах, где это требуется, включая весь общедоступный API, который обращается к коллекции.

Реальная опасность заключается в том, что, блокируя тип, который открыт или может быть открыт для внешнего мира, вы потенциально открываете возможность для «внешнего мира» связываться с вашей синхронизацией. Если используется более одной блокировки, это может привести к мертвым блокировкам (если внешняя блокировка на что-то, чего вы не ожидаете).

Создавая личную переменную и блокируя ее исключительно, вы «контролируете» ситуацию. Это делает намного более ясным, что происходит. Кроме того, он облегчает синхронизацию между несколькими объектами, особенно позже, когда вы поддерживаете код, поскольку блокировка очень проста.

1 голос
/ 29 июня 2011

Никогда не блокируйте SyncRoot, потому что я считаю, что он блокирует (это) блокировку всей коллекции. Если вы собираетесь заблокировать, вы должны создать объект и заблокировать его. Например

public class MyClass
{
   get {return lock(_lockObject) _myCollection ; }
   set {lock(_lockObject) _myCollection.Add(value); }


   private List<string> _myCollection = new List<string>();
   private object _lockObject = new object();
}

Чтобы лучше уточнить, Блокировка (myCollection.SyncRoot) и блокировка (myCollection) выполняют одно и то же.
Потому что свойство SyncRoot выглядит примерно так

получить {вернуть это; }

...