nfp*_*lee 2 c# asp.net-mvc concurrency multithreading
我一直在构建ASP.NET MVC应用程序,当我启动它时,我担心潜在的多线程问题.一个特别值得关注的是以下代码:
private static IDictionary<string, ISettings> _settingsDictionary = new Dictionary<string, ISettings>();
public T Settings<T>() where T : ISettings, new() {
var key = typeof(T).FullName;
if (!_settingsDictionary.ContainsKey(key))
_settingsDictionary[key] = _settingsService.GetSettings<T>();
return (T)_settingsDictionary[key];
}
Run Code Online (Sandbox Code Playgroud)
请注意,字典定义为静态.这允许我缓存字典,以便它为应用程序长度的每个请求返回相同的实例.
这在本地测试时工作正常,但我担心它可能会被数百名用户使用.这让我研究了ConcurrencyDictionary.请问你能告诉我是否需要使用它以及如果是这样的话我会怎么做.
谢谢
是的,这里有潜在的数据竞争:
if (!_settingsDictionary.ContainsKey(key))
_settingsDictionary[key] = _settingsService.GetSettings<T>();
Run Code Online (Sandbox Code Playgroud)
这可能导致两个线程添加相同的密钥,因为它们可以在任何时候中断.
您可以使用ConcurrentDictionary.GetOrAdd代替:
private static ConcurrentDictionary<string, ISettings> _settingsDictionary = new ConcurrentDictionary<string, ISettings>();
public T Settings<T>() where T : ISettings, new() {
var key = typeof(T).FullName;
return _settingsDictionary.GetOrAdd(key, _settingsService.GetSettings<T>());
}
Run Code Online (Sandbox Code Playgroud)
编辑:由于您不希望_settingsService.GetSettings<T>()每次都执行,替代方案可能是:
private static IDictionary<string, ISettings> _settingsDictionary = new Dictionary<string, ISettings>();
private static object locker = new object();
public T Settings<T>() where T : ISettings, new() {
var key = typeof(T).FullName;
lock(locker)
{
if (!_settingsDictionary.ContainsKey(key))
_settingsDictionary[key] = _settingsService.GetSettings<T>();
return (T)_settingsDictionary[key];
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |