#.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. Даже я не понимаю свой первый комментарий 🙂 в любом случае удаляю его.