C# 与极限一致

C# 与极限一致,c#,performance,dictionary,reflection,concurrency,C#,Performance,Dictionary,Reflection,Concurrency,我正在写一些使用反射的代码。因此,我试图将昂贵的反射处理缓存到ConcurrentDictionary中。但是,我希望对并发字典应用一个限制,以防止存储旧的和未使用的缓存值 我做了一些研究,看看如何限制ConcurrentDictionary的大小。我发现了一些有趣的答案,但我不知道这些答案是否符合我的要求,是否会表现良好 我在源代码中发现,他们编写了一些自定义代码来处理ConcurrentDictionary的限制。它们有一个集合限制常量,用于处理字典的并发性 另一方面,我发现了一个On-SO

我正在写一些使用反射的代码。因此,我试图将昂贵的反射处理缓存到
ConcurrentDictionary
中。但是,我希望对并发字典应用一个限制,以防止存储旧的和未使用的缓存值

我做了一些研究,看看如何限制
ConcurrentDictionary
的大小。我发现了一些有趣的答案,但我不知道这些答案是否符合我的要求,是否会表现良好

我在源代码中发现,他们编写了一些自定义代码来处理
ConcurrentDictionary
的限制。它们有一个集合限制常量,用于处理字典的并发性

另一方面,我发现了一个On-SO,它使用一个普通字典,然后在其上应用一个
readerwriterlocksim
来处理并发性。我不知道它是否与.Net源代码中的实现相同

我应该使用dapper实现还是SO-answer实现?

关于“缓存信息”的确切方式在环境方面有很多不同。像WebDevelopment这样的领域需要完全不同的方法,这要归功于环境的大规模并行性和高度的分离

但是缓存任何东西的核心是WeakReference。强引用阻止GC进行收集。weakreference没有,但允许您获得强引用。这是程序员的说法,“不要为了这个列表而把它保存在内存中。但是如果你还没有收集到它,请给我一个有力的参考。”


从本质上讲,GC只能在所有其他线程暂停时收集(或标记该主线程的弱引用)。因此,weakreference不应该让您暴露于额外的竞争条件下——它要么仍然存在,而您现在有一个强引用,要么没有。

为了提高性能,您根本不应该使用锁定。另外,请注意
ConcurrentDictionary
类中隐藏的性能瓶颈,例如,枚举集合时会创建垃圾(请参阅问题)

使用 反射缓存唯一合理的解决方案是为每个线程提供一个单独的字典。是的,这需要一些RAM,但是性能会更好

公共静态类类型扩展
{
[ThreadStatic]私有静态字典属性inFolookup;
私有静态字典MemberInfoLookup=>
propertyInfoLookup???=新字典();
//示例API
公共静态属性info GetPropertyInfo(此类型)=>MemberInfoLookup[Type];
}

嘿,现在不要认为“整洁”是完美的代码;这只是第一件工作得足够好的事情,我们还没有回去重构它-它不应该被视为一个例子。。。嗯,什么都可以,真的;选择此处的示例或第三个选项取决于上下文(我们没有)和意见(我们不希望),您可以使用.Net已经实现的缓存类和一些示例,我认为这是最好的方法。@Marc Gravell:我知道这是实现并发字典的一种方法,你可以用很多方法来实现它。我想用一条线来清理字典。我还考虑使用一个队列来保存最后的X记录。我知道答案是主观的,实现可能会有所不同。@OscarVicentePerez:你说的是什么类?这是非常错误的,RWLS不能确保多个读者不能同时访问字典。使用
ConcurrentDictionary
对我来说非常重要。我将阅读有关WeakReference的内容,以检查它是否对我有帮助。@billybob为什么使用
ConcurrentDictionary
?实际上,如果键和值都是ref类型,你会惊讶地发现你能用
哈希表
(是的,我的意思是
哈希表
,而不是
字典
),它实际上有一个很好的线程模型,尽管它有一个弱类型模型
WeakReference
,当然可以是缓存实现的一部分,但您希望事物是可收集的并不是自动的-有时,缓存的价值比简单的GC要求更高,因此您需要其他逐出机制-TTL、LRU、,etc@MarcGravell:我想我记得一些缓存类具有这样的功能。甚至可以注册一些非托管内存来执行它的工作。我想我找到了一个清单:显然,他们在4.0中为此添加了一个完整的名称空间。@MarcGravel:我看不到使用
哈希表然后自己重新实现并发的效用。我发现有两种方法可以解决这个问题。或者,我采用现有的实现<代码>ConcurrentDictionary
在本例中,并在其上添加限制。或者,我在字典上重新编码并发性,并对其应用限制。另外,我不想使用哈希表,因为它不是泛型的,我可能在其他地方使用“有限字典”。我不知道
ThreadStatic
!很酷。但是它是如何应用于这个问题的呢?一旦你有了一个独立的、性能良好的容器,你就可以很容易地连续循环并删除不再需要的缓存值(例如通过计时器)。当然,我可以改进我的答案,将其包括在内。我只是想快速保护OP的代码,使其不会以不必要的锁定结束P