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