System.Configuration 的线程安全使用
是否有一种简单的方法可以通过线程安全接口访问自定义的基于 System.Configuration 的配置数据,而不需要每个执行上下文加载/重新加载配置信息,这在计算上会很繁重?
System.Configuration 类与 Microsoft .Net 库文档中的大多数(所有?)其他类一样,都使用以下线程安全信息进行注释:
此类型的任何公共静态(在 Visual Basic 中为共享)成员都是线程安全的。 不保证任何实例成员都是线程安全的。
通过我的阅读,从 ConfigurationManager.GetSection(string)
和其他类似方法返回的 ConfigurationSection
对象(例如 OpenExeConfiguration(string exePath).GetSection(string )
) 不得被假定为线程安全的,因此不应被多个执行上下文使用。 这禁止将 ConfigurationSection
存储在单例中,否则该单例是线程安全的,因为虽然对节对象的访问可能是安全的,但对象本身的成员并不安全。
然而,多次调用 GetSection
可能需要重新解析配置文件并分配新的 ConfigurationSection
实例,考虑到配置不太可能永远存在,这会产生很高的开销初始化后改变。 此外,将配置数据复制到另一个线程安全的对象中似乎首先破坏了使用内置配置包的主要好处之一(轻松访问类型转换和验证的配置信息,无需太多样板代码)。
那么,有没有一种方法可以以线程安全的方式使用 System.Configuration ,而不需要过度解析和分配配置节呢? 即使您通过 System.Configuration
接口访问它,实现您自己的 ConfigurationSection
是否可以使您免受 Microsoft 提供的保证的缺乏(如果是这样,您将如何当需要访问基本 ConfigurationSection
的索引器来访问配置的数据时,是否将其实现为线程安全的)?
Is there an easy method of accessing custom System.Configuration-based configuration data through a thread-safe interface without requiring each execution context from loading/reloading configuration information which would be computationally burdensome?
System.Configuration classes, like most (all?) other classes in Microsoft's .Net library documentation, are annotated with the following thread-safety information:
Any public static (Shared in Visual Basic) members of this type are thread safe.
Any instance members are not guaranteed to be thread safe.
By my reading of this, the ConfigurationSection
objects returned from the ConfigurationManager.GetSection(string)
and other similar methods (e.g. OpenExeConfiguration(string exePath).GetSection(string)
) must not be assumed to be thread-safe and thus should not be used by multiple execution contexts. This prohibits storing a ConfigurationSection
in a singleton that would otherwise be thread-safe because while the access to the section object may be safe, the members on the object itself are not safe.
Multiple calls to GetSection
, however, are likely to require re-parsing of the configuration files and allocating new ConfigurationSection
instances which has a high overhead considering the configuration is not likely to ever change after initialization. Further, copying the configuration data into another object that has been made thread-safe seems to defeat one of the main benefits of using the built-in configuration package in the first place (easy access to type-converted and validated configuration information without much boilerplate code).
So, is there a way to use System.Configuration
in a thread-safe manner without resorting to excess parsing and allocations of configuration sections? Does implementing your own ConfigurationSection
free you from the lack of guarantee provided by Microsoft even though you're accessing it through the System.Configuration
interfaces (and if so, how would you implement it to be thread-safe when access to the base ConfigurationSection
's indexer is required for accessing the configured data)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从 GetSection 返回的实例不是线程安全的。 这意味着您需要添加锁定代码才能在单例中使用它。
多次调用不会重新解析文件,除非文件已更改。 数据缓存在内存中。
您的线程安全问题可以通过使用锁定轻松解决(我不确定您是否需要这样做,除非您在运行时更改配置),并且不存在性能问题。
The instance returned from GetSection is not thread-safe. That means you need to add locking code in order to use it in your singleton.
Multiple calls do not re-parse the file, unless the file has changed. The data are cached in memory.
Your thread safety problem is easily solved by using locking (I'm not sure you'll need to, unless you're changing the configuration at runtime), and there is no performance problem.
ConfigurationManager.GetSection(string) 是一个公共静态成员,并且由于 msdn 声明“此类型的任何公共静态(在 Visual Basic 中共享)成员都是线程安全的”,因此您可以假设它可以安全使用。
至于性能,我愿意假设 MS 已经使其非常高效,并且只需按原样使用它们的功能即可。 请记住:过早的优化是万恶之源。
ConfigurationManager.GetSection(string) is a public static member, and since msdn states 'Any public static (Shared in Visual Basic) members of this type are thread safe', you can assume it's safe to use.
As for performance, i'd be willing to assume that MS has made it pretty efficient already and just use their functions as is. Remember: premature optimization is the root of evil.