Потокобезопасное использование System.Configuration
-
09-09-2019 - |
Вопрос
Существует ли простой метод доступа к пользовательским данным конфигурации на основе System.Configuration через потокобезопасный интерфейс, не требующий загрузки/перезагрузки каждого контекста выполнения информации о конфигурации, что было бы обременительно в вычислительном отношении?
Классы System.Configuration, как и большинство (все?) других классов в документации библиотеки Microsoft .Net, помечены следующей информацией о потокобезопасности:
Любые общедоступные статические (Shared в Visual Basic) члены этого типа являются потокобезопасными.Потокобезопасность любых членов экземпляра не гарантируется.
Судя по моему прочтению этого, ConfigurationSection
объекты, возвращенные из ConfigurationManager.GetSection(string)
и другие подобные методы (например. OpenExeConfiguration(string exePath).GetSection(string)
) не должен считаться потокобезопасным и, следовательно, не должен использоваться в нескольких контекстах выполнения.Это запрещает хранение ConfigurationSection
в синглтоне, который в противном случае был бы потокобезопасным, поскольку, хотя доступ к объекту раздела может быть безопасным, члены самого объекта небезопасны.
Несколько обращений к GetSection
, однако, скорее всего, потребуется повторный анализ файлов конфигурации и выделение новых ConfigurationSection
экземпляры, которые требуют больших затрат, учитывая, что конфигурация вряд ли когда-либо изменится после инициализации.Кроме того, копирование данных конфигурации в другой объект, который стал потокобезопасным, по-видимому, сводит на нет одно из основных преимуществ использования встроенного пакета конфигурации (легкий доступ к преобразованной и проверенной информации о конфигурации без использования шаблонного кода). код).
Итак, есть ли способ использовать System.Configuration
потокобезопасным образом, не прибегая к дополнительному анализу и выделению разделов конфигурации?Реализует ли ваш собственный ConfigurationSection
освободить вас от отсутствия гарантии, предоставляемой Microsoft, даже если вы получаете к нему доступ через System.Configuration
интерфейсы (и если да, то как бы вы реализовали их для обеспечения потокобезопасности при доступе к базе данных? ConfigurationSection
индексатор требуется для доступа к настроенным данным)?
Решение
Экземпляр, возвращаемый из GetSection, не является потокобезопасным.Это означает, что вам нужно добавить код блокировки, чтобы использовать его в своем синглтоне.
Множественные вызовы не выполняют повторный анализ файла, если только файл не изменился.Данные кэшируются в памяти.
Ваша проблема с потокобезопасностью легко решается с помощью блокировки (я не уверен, что вам это понадобится, если только вы не меняете конфигурацию во время выполнения), и проблем с производительностью не возникает.
Другие советы
ConfigurationManager.GetSection(string) является общедоступным статическим членом, и поскольку msdn заявляет: «Любые общедоступные статические (общие в Visual Basic) члены этого типа являются потокобезопасными», вы можете предположить, что его безопасно использовать.
Что касается производительности, я бы предположил, что MS уже сделала ее довольно эффективной и просто использует свои функции как есть.Помнить:преждевременная оптимизация — корень зла.