gpt4 book ai didi

c# - 当我的哈希表缓存实现被清除时,我应该如何使它安全?

转载 作者:行者123 更新时间:2023-11-30 19:51:08 27 4
gpt4 key购买 nike

我有一个类用于缓存对数据库资源的访问。它看起来像这样:

//gets registered as a singleton
class DataCacher<T>
{
IDictionary<string, T> items = GetDataFromDb();

//Get is called all the time from zillions of threads
internal T Get(string key)
{
return items[key];
}

IDictionary<string, T> GetDataFromDb() { ...expensive slow SQL access... }

//this gets called every 5 minutes
internal void Reset()
{
items.Clear();
}
}

我已经稍微简化了这段代码,但它的要点是存在潜在的并发问题,因为在清除项目时,如果调用 Get,事情可能会出错。

现在我可以将锁 block 插入 Get 和 Reset 中,但我担心 Get 上的锁会降低站点的性能,因为 Get 被 Web 应用程序中的每个请求线程调用了很多次。

我认为我可以使用经过双重检查的锁来做一些事情,但我怀疑有一种比 lock{} block 更智能的方法可以做到这一点。怎么办?

编辑:抱歉,我之前没有明确说明,但我使用的 items.Clear() 实现实际上并不是一个直接的字典。它是 ResourceProvider 的包装器,它要求字典实现在每个项目被删除时调用 .ReleaseAllResources() 。这意味着调用代码不想针对正在处理的旧版本运行。鉴于此,Interlocked.Exchange 方法是否正确?

最佳答案

我会开始只用一个来测试它;没有竞争时,锁非常便宜。然而 - 一个更简单的方案是依赖于引用更新的原子性:

public void Clear() {
var tmp = GetDataFromDb(); // or new Dictionary<...> for an empty one
items = tmp; // this is atomic; subsequent get/set will use this one
}

您可能还想使 items 成为一个 volatile 字段,只是为了确保它不会保存在任何地方的寄存器中。

这仍然存在一个问题,即任何期望有给定 key 的人可能会感到失望(通过异常),但这是一个单独的问题。

更精细的选项可能是 ReaderWriterLockSlim .

关于c# - 当我的哈希表缓存实现被清除时,我应该如何使它安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1554158/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com