【问题标题】:Generic implementation of System.Runtime.Caching.MemoryCacheSystem.Runtime.Caching.MemoryCache 的通用实现
【发布时间】:2017-10-25 07:38:48
【问题描述】:

MemoryCache 是否有任何通用的替代方案/实现?

我知道 MemoryCache 在底层使用 Hashtable,因此只需转换为使用 Dictionary,它是 Hashtable 的通用版本。

这将提供类型安全并提供性能优势,因为没有装箱/拆箱。

编辑:我感兴趣的另一件事是拥有不同的密钥类型。默认为 System.String。

【问题讨论】:

  • 但是你只能缓存一种类型?我不会太担心这个成本,装箱部分在原始值类型上可以忽略不计。
  • @AdamHouldsworth:是的,这是有意的。我用滑动过期将缓存包裹在一个数据库映射上,它只返回一种类型。
  • 那么除了类型安全之外,您不会从泛型实现中获得任何好处。我会围绕 MemoryCache 创建一个瘦包装类,它知道您感兴趣的类型,然后所有调用代码都可以以强类型的方式使用包装。
  • 有一个叫做 LazyCache 的东西,它是一个 NuGet 包。最新版本似乎已经测试了将近一年,但人们说它很稳定。

标签: c# generics caching optimization


【解决方案1】:

MemoryCache 是否有任何通用的替代方案/实现?

不在基类库中。你必须自己动手,不过我个人只会对 MemoryCache 进行包装,以提供你想要的 API。

这将提供类型安全并提供性能优势,因为没有装箱/拆箱

类型安全可以在包装类中相当容易地处理。只有当您存储值类型(而不是类)时,装箱/拆箱才会成为问题,即使那样,也可能是最小的,因为您不太可能经常从缓存中推送和拉取以使其成为真正的性能问题。

至于类型安全性和可用性,我实际上已经编写了自己的方法来将MemoryCache 项目的调用包装在一个通用的方法 中,从 API 的角度来看,这可以更好地使用。这非常简单——通常只需要一个类似的方法:

public T GetItem<T>(string key) where T : class
{
    return memoryCache[key] as T;
}

同样地,你可以用同样的方法来设置值。

编辑:我感兴趣的另一件事是拥有不同的密钥类型。默认为 System.String。

MemoryCache 不直接支持此功能,因此需要大量工作才能生成自己的密钥。一种选择是制作一个类型安全的包装器,它还提供了一个Func&lt;T, string&gt;,以根据您的值生成一个字符串键——这将允许您为任何类型的T 生成一个缓存条目。当然,您必须小心在字符串中包含您想要作为比较的一部分的所有数据。

【讨论】:

  • 我认为装箱/拆箱是一个有效的问题 - 如果您确实在缓存值类型。使用缓存的主要原因之一是因为您正在以高频率计算值。因此,缓存经常被命中是很常见的情况。也许受到足够打击而使装箱变得昂贵是一种不寻常的情况,但这取决于您的应用程序对 GC 压力的敏感程度
  • 我不知道。不是。
【解决方案2】:

我写了我的,FWIW:

https://github.com/ysharplanguage/GenericMemoryCache#readme(链接失效)

这里有一个原代码的fork:

https://github.com/caesay/GenericMemoryCache

【讨论】:

  • 看起来很有趣,是恢复老问题的好方法。我一定会看看并尝试一下!
猜你喜欢
  • 1970-01-01
  • 2011-04-22
  • 1970-01-01
  • 2011-12-24
  • 2010-09-06
  • 2012-08-21
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
相关资源
最近更新 更多