Как работает SyncLock в .Net

#.net #vb.net #multithreading #synclock

#.net #vb.net #многопоточность #синхронизация

Вопрос:

У меня есть список объектов, совместно используемых несколькими потоками, иногда он генерирует исключение IndexOutOfRangeException при попытке Clear . При поиске решения я обнаружил, что мне следует использовать SyncLock при доступе к списку.

Но мой вопрос, если в чем важность блока lockObject in SyncLock , например, при очистке myList , могу ли я использовать

 Synclock myList
    myList.Clear
End SyncLock
  

или lockObject должен отличаться от myList?

Редактировать:

Что я думаю о sysnclock, так это «блокировка получается для объекта, указанного как lockObject». Что, если я укажу list для очистки как lockObject, не должен ли компилятор получить эксклюзивный доступ к list перед его очисткой?

Ответ №1:

Выбор произвольный — ссылка может быть полностью независимой от данных, к которым вы обращаетесь внутри блока, или вы можете использовать что-то вроде ссылки на список.

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

Обратите внимание, что вы не должны использовать блокировку только для очистки — вам нужно будет использовать ее везде, где вы обращаетесь к списку.

Комментарии:

1. спасибо за ваш ответ. но еще один вопрос… что понятно из sysnclock, так это то, что блокировка получается для объекта, указанного как lockObject . Что, если я укажу list для очистки как lockObject, не должен ли компилятор получить эксклюзивный доступ к list перед его очисткой?

2. @regexhacks: Нет, компилятор не собирается автоматически вставлять для вас блокировки. Вы этого не хотите — обычно вы не используете объекты из нескольких потоков, так почему вы хотите, чтобы это увеличивало стоимость блокировки? Я не совсем понимаю ваш первый комментарий — как я уже сказал, вам нужно заблокировать везде , где вы обращаетесь к списку. На этом этапе не будет никаких шансов, что к списку можно будет получить доступ одновременно из нескольких потоков.

3. Даже я не понимаю свой первый комментарий 🙂 в любом случае удаляю его.