gpt4 book ai didi

c# - 对于 .NET 3.5,您将如何进行线程安全的获取或添加缓存?

转载 作者:太空狗 更新时间:2023-10-29 19:44:36 24 4
gpt4 key购买 nike

我开始使用一些 .NET 3.5 代码并发现以下扩展方法用于缓存::

public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> @this, TKey key,Func<TKey,TValue> factory,bool useLocking)
{

TValue value;
if(!@this.TryGetValue(key,out value))
{
if (useLocking)
{
lock ((@this as ICollection).SyncRoot)
{
if (!@this.TryGetValue(key, out value))
{
@this[key] = value = factory(key);
}
}
}
else
{
@this[key] = value = factory(key);
}
}
return value;
}

有问题的缓存由字符串键作为键控,并且 useLocking = true。它总是通过这种方法访问(没有流浪 TryGetValue )。使用 SyncRoot 也没有问题属性,因为字典是私有(private)的,没有其他地方使用它。双重锁定是危险的,因为字典在写入时不支持读取。虽然技术上还没有报告任何问题,因为产品尚未发货,但我认为这种方法会导致竞争条件。

  1. 切换Dictionary<,>Hashtable .我们将失去类型安全性,但我们将能够支持我们所追求的并发模型(1 个写入者,多个读取者)。

  2. 删除外部 TryGetValue。这样每次读取都需要获取锁。这可能对性能不利,但获取无竞争锁的成本应该相当低。

两者都很糟糕。有人有更好的建议吗?如果这是 .NET 4 代码,我会将其切换为 ConcurrentDictionary ,但我没有那个选项。

最佳答案

是的,你的怀疑是正确的;存在竞争条件,所有方法,甚至 TryGetValue 都需要在您提供的实现中的锁内。

就性能而言,您可以期待升级到 .NET4 的那一天,其中包括开箱即用的快得惊人的 ConcurrentDictionary。在此之前,您可以在此处查看 James Michael Hare 的分析:

这些结果向我表明,.NET3.5 的最佳实现是 Dictionary 加上 ReadWriteLockSlim,为了更好的衡量,这里有一个完整的实现:

更新:

我读错了表格,看起来 Dictionary + lock 比唯一的其他重要竞争者 Dictionary + 快一点ReadWriteLockSlim.

关于c# - 对于 .NET 3.5,您将如何进行线程安全的获取或添加缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4473897/

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