Приемлемо для блокировки (AppDomain.CurrentDomain)? - PullRequest
4 голосов
/ 24 февраля 2010

Я хочу перечислить все загруженные сборки в приложении Asp.NET, используя AppDomain.CurrentDomain.GetAssemblies(). Однако при проверке документации для AppDomain я нахожу следующее утверждение:

Безопасность потоков

Любые открытые статические (Shared в Visual Basic) члены этого типа являются потокобезопасными. Ни один из членов экземпляра не гарантированно является потокобезопасным.

Поскольку GetAssemblies() - это метод экземпляра, я использую его, поскольку должен сделать какую-то блокировку вокруг этого вызова, если не для чего-либо еще, чтобы не позволить кому-либо еще загрузить новую сборку в домен, пока я перечисляя текущие. Я ожидаю, что AppDomain предоставит какое-то свойство SyncRoot, но это не так, и я не нашел в Интернете никакой информации о том, как это сделать.

Как мне синхронизировать этот вызов?

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

  1. Я знаю, что оператор блокировки используется для создания кооперативной блокировки, именно поэтому я хочу заблокировать домен приложений точно так же, как все остальные (или должны делать), вместо того, чтобы создать свою собственную блокировку, которая выиграла не мешает загружать сборки сборкам, пока я их перечисляю.
  2. Я знаю, что блокировки, которые могут быть использованы кем-либо, обычно плохая идея, но я также знаю, что не блокировка при выполнении небезопасных операций еще хуже.
  3. Оба ответа пока что говорят о том, что GetAssemblies () фактически является поточно-ориентированным. Это имеет смысл для меня, и я действительно ожидал бы, что это так, но откуда вы это знаете? У кого-нибудь есть ссылка в поддержку этого утверждения? Мой гугл-фу подвел меня, и Reflector показывает, что этот метод является тонкой оболочкой для внутреннего встроенного метода.

Ответы [ 2 ]

2 голосов
/ 24 февраля 2010

Свойства SyncRoot вообще очень плохая идея. Одна из причин, по которой это возможно для 2 независимо разработанных библиотек, неосознанно принять решение о блокировке общего свойства SyncRoot и быстро ввести взаимоблокировки в приложение. Блокировка - это операция, которая не может быть легко разделена между двумя независимыми компонентами. Лучшей стратегией здесь является разработка собственной блокировки, которая используется вашими компонентами для синхронизации доступа.

В этом случае, хотя вызов GetAssemblies безопасен для нескольких потоков, поэтому блокировка не требуется. Предупреждение, которое вы видите, является общим утверждением, добавленным к каждому классу в BCL, если автор специально не разработал тип для безопасности потока и не удалил сообщение.

1 голос
/ 24 февраля 2010

Это стандартный отказ от ответственности; вам не нужно беспокоиться об этом.
В общем, если вы (или другой поток) не изменяете объект, методы экземпляра могут вызываться из нескольких потоков.

Обратите внимание, что вы никогда не должны блокировать объект AppDomain .

...