c# - 使用 ConcurrentDictionary 作为缓存并处理更新

标签 c# .net parallel-processing concurrentdictionary

我有下面的代码,现在我想添加一个 UpdateSetting 方法。

我能看到的最好的方法是通过 ConcurrentDictionary 上的 TryUpdate 但这意味着知道以前的值,因此需要调用 GetSetting 这看起来有点恶心。你怎么看?有没有更好的办法?

注意:如果值不在缓存中,则什么都不做。成功更新缓存后,它应该调用 settingRepository.Update

谢谢

public class MySettings : IMySettings
    {
        private readonly ISettingRepository settingRepository;
        private readonly ConcurrentDictionary<string, object> cachedValues = new ConcurrentDictionary<string, object>();


        public MySettings(ISettingRepository settingRepository)
        {
            this.settingRepository = settingRepository;
        }

        public string GetSetting(string key)
        {
            return this.GetSetting<string>(key);
        }

        public T GetSetting<T>(string key)
        {
            object value;
            if (!this.cachedValues.TryGetValue(key, out value))
            {
                value = this.GetValueFromRepository(key, typeof(T));
                this.cachedValues.TryAdd(key, value);
            }

            return (T)value;
        }

        private object GetValueFromRepository(string key, Type type)
        {
            var stringValue = this.settingRepository.GetSetting(key);
            if (stringValue == null)
            {
                throw new MissingSettingException(string.Format("A setting with the key '{0}' does not exist.", key));
            }

            if (type == typeof(string))
            {
                return stringValue;
            }

            return ConvertValue(stringValue, type);
        }

        private static object ConvertValue(string stringValue, Type type)
        {
            return TypeDescriptor.GetConverter(type).ConvertFromString(stringValue);
        }

    }

最佳答案

可能值得获取现有值以避免更新存储库。如果比尝试更昂贵,则异常(exception)

public bool UpdateSetting<T>(string key, T value)
{
    lock 
    {
        T oldValue;            
        if (this.cachedValues.TryGetValue(key, out oldValue)
        {
            if (oldValue != value)
            {
                this.cachedValues[key] = value;
                settingRepository.Update(key, value);
            }
            return true;
        } 
        else 
        { 
           return false;
        }            
    }
}

关于c# - 使用 ConcurrentDictionary 作为缓存并处理更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28116318/

相关文章:

c#.net 网络服务

c# - 为什么 WPF 中的依赖属性必须是静态的

c# - 顺序执行的纯计算任务

c# - 使用带有 bindinglist<business obj> 的绑定(bind)源作为数据源有什么好处?

.net - 如何避免 XML 注入(inject)

powershell - 如何退出 ForEach-Object Parallel 并更新 Powershell 7 中运行空间之外的变量?

perl - 如何等待子进程在父进程中设置变量?

C# 查询 XML 文档

c# - NHibernate 延迟加载但没有虚拟属性?

c# - 如何获取 C# 中的总物理内存?