潜在的并发问题? [英] Potential Concurrency Issue?

查看:108
本文介绍了潜在的并发问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在构建ASP.NET MVC应用程序,我在启动它时担心潜在的多线程问题.以下代码是一个特别需要关注的地方:

I have been building ASP.NET MVC application and I'm worried about potential multi-threading issues when I launch it. One particular concern is the following code:

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];
}

请注意,字典已定义为静态字典.这使我可以缓存字典,以便它为应用程序长度的每个请求返回相同的实例.

Notice the dictionary is defined as static. This allows me to cache the dictionary so that it returns the same instance for every request for the length of the application.

这在本地测试时效果很好,但我担心数百名用户使用它时可能会受到影响.这导致我研究了ConcurrencyDictionary.请问我是否需要使用它以及在这种情况下该如何使用.

This works fine when testing locally but i'm worried it may suffer when used by hundreds of users. This has led me to investigate the ConcurrencyDictionary. Please could you advise me on whether I need to use it and how i would go about doing so if that is the case.

谢谢

推荐答案

是的,这里存在潜在的数据竞争:

Yes there is a potential data race here:

if (!_settingsDictionary.ContainsKey(key))
    _settingsDictionary[key] = _settingsService.GetSettings<T>();

这可能导致两个线程添加相同的密钥,因为它们可以随时被中断.

which could cause two threads to add the same key, since they can be interrupted at any point.

您可以使用 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>(),因此可以选择以下替代方法:

Edit: Since you don't want _settingsService.GetSettings<T>() to be executed every time, an alternative could be:

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];
    }
}

这篇关于潜在的并发问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆