我有一个类,它在实例化时会读取web.config文件。
我需要更改此逻辑,因此读取只发生一次(第一次创建实例),然后数据在生命周期内保持静态。
public AuthenticationProviderFactory()
{
TraceManager = new Lazy<ITraceManager>(() => new TraceManager()).Value;
AuthenticationProviders =
new Lazy<IDictionary<string, IAuthenticationProvider>>(
() => new Dictionary<string, IAuthenticationProvider>()).Value;
Initialize();
}
没有什么可复杂的。创建字典然后初始化它。
为了简单起见(在这个问题中),我们只需说Initialize()
只是从web.config文件中读取数据。从某处获取数据并将其粘贴到字典中。
现在我希望改变它,所以第一次创建这个类时,我创建一次字典(因此,它应该是静态的),然后将数据读入其中一次。
我在想这个但不确定这是否可以接受: -
private static Lazy<IDictionary<string, IAuthenticationProvider>> _authenticationProviders;
private static bool _hasParsedConfigFile = false;
public AuthenticationProviderFactory()
{
TraceManager = new Lazy<ITraceManager>(() => new TraceManager()).Value;
_authenticationProviders =
new Lazy<IDictionary<string, IAuthenticationProvider>>(
() =>
{
var authenticationProviders =
new Dictionary
<string, IAuthenticationProvider>();
if (!_hasParsedConfigFile)
{
Initialize();
_hasParsedConfigFile = true;
}
return authenticationProviders;
});
Initialize();
}
public static IDictionary<string, IAuthenticationProvider> AuthenticationProviders
{
get { return _authenticationProviders.Value; }
}
注意我是怎么想的,我更多地创造了懒惰的词典..懒惰:我还想知道这里的竞争条件是否会引起问题,我可能需要加倍-null锁定...但是听说双零锁定并不是非常好的螺纹安全/竞争条件,解决方案。
有人有什么建议吗?
答案 0 :(得分:0)
我更喜欢在静态构造函数中初始化数据,这意味着您的代码将是
static AuthenticationProviderFactory()
{
AuthenticationProviders =
new Lazy<IDictionary<string, IAuthenticationProvider>>(
() => new Dictionary<string, IAuthenticationProvider>()).Value;
Initialize();
}
但是这不会使用延迟加载,因为一旦访问类就会加载数据。
所以要使用延迟加载我建议使用如下的静态属性:
private readonly object writeLock = new object();
private static Lazy<IDictionary<string, IAuthenticationProvider>> _authenticationProviders;
private static bool _hasParsedConfigFile = false;
public static IDictionary<string, IAuthenticationProvider> AuthenticationProviders
{
get
{
if (!_hasParsedConfigFile)
{
lock (writeLock)
{
if (!_hasParsedConfigFile)
{
_authenticationProviders = new Dictionary<string, IAuthenticationProvider>();
Initialize();
_hasParsedConfigFile = true;
}
}
}
return _authenticationProviders;
}
}