我一直在构建 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];
}
注意字典被定义为静态的。这允许我缓存字典,以便它为应用程序长度的每个请求返回相同的实例。
这在本地测试时工作正常,但我担心当数百名用户使用时它可能会受到影响。这促使我调查 ConcurrencyDictionary。请告诉我是否需要使用它以及如果是这种情况我将如何去做。
谢谢
最佳答案
是的,这里存在潜在的数据竞争:
if (!_settingsDictionary.ContainsKey(key))
_settingsDictionary[key] = _settingsService.GetSettings<T>();
这可能会导致两个线程添加相同的 key ,因为它们可以随时被中断。
你可以使用 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>());
}
编辑:既然你不想_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];
}
}
关于c# - 潜在的并发问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12176216/