.NET简单内存缓存

8
简而言之,.Net生态系统中存在哪些简单的内存缓存?我正在寻找以下内容:
- 无需配置(除了简单的API调用)。我不想使用外部配置文件,因为它们只会使部署变得复杂。 - 同一进程(不是某个外部进程或服务器)。最好像这样创建:var myCache = new SimpleCache(1024 * 1024 * 100); // 100 MB - 指定内存限制 - 基于最少使用而清除缓存项 - 基于时间过期(非必需,但在其他场景中可能有用) - 与.Net 3.5兼容
我已经研究了以下选项:
  • ASP.Net System.Web.Caching
    • 它的API不支持对缓存大小的任何控制,也不支持基于使用情况的优先级。因此,当它决定有足够的内存压力来清空缓存时,您完全取决于它。
  • System.Runtime.Caching
  • Microsoft Enterprise Library - Caching Block
    • 除了声称臃肿之外,我不喜欢使用XML文件或app.config进行配置。此外,虽然它支持基于存储的对象数量限制缓存的大小,但它没有限制这些对象大小的机制。
  • NCache
    • 可能对我想要的用例过度,但最重要的是,它是一款付费产品,这不是我想要处理的事情(相比之下,我只需在一两天内编写一个)。通常,其Express版本具有使用限制,不鼓励将其用于任何生产目的。
  • MemCacheD
    • 与我想要的完全相反(外部分布式进程)
我正在使用Google Protocol Buffers (protobuf-net)进行编程,因此我对每个项的内存占用有相对准确的估计。我正在缓存从数据库访问返回的数据,但我不想使用正式的ORM(实际上我正在使用PetaPoco,但这是无关紧要的)。
在这个阶段,我计划实现自己的缓存,使用双向链表和哈希(字典)来提供一旦达到缓存限制就能够删除最近最少使用的缓存项。然而,在我自己实现之前,我想检查是否有任何适合的选项。

1
这只是从来不简单的事情,一个没有良好过期策略的缓存就像内存泄漏一样。不喜欢现有的东西总是建立自己的第一动力。 - Hans Passant
我想指定一个最大的内存占用量,而不是一个过期策略。在 .Net 中,你无法真正测量对象占用了多少内存,但我正在使用的协议缓冲区有一个相当有用的度量方式。 - Matt G
如果您将其开发为相当通用的缓存,那么或许可以将其放在CodeProject或类似网站上供他人使用?制作一个简单的原型并获得高测试覆盖率应该非常简单。 - Mike
Mare Infinitus提供的链接http://www.codeproject.com/Articles/7684/Using-C-Generics-to-implement-a-Cache-collection是我使用的基础。虽然我将来可能需要使它更加通用,但由于它是一个特定用例(目前不使用泛型),而且它是我的雇主的知识产权,我怀疑我不会将其放在CodeProject上。 - Matt G
4个回答

3
那么你最终是怎么处理缓存的呢?
我有一个通用缓存的原型,可以做到几乎与你想要的一样,除了缓存限制是根据容量(项目数量)而不是内存使用情况,但它还有一个额外的功能,你可能会喜欢:本地持久化。
缓存按层结构化,其中可以有单层:内存,双层:内存+本地持久化,或三层:内存+本地持久化+网络共享。您可以根据需要使用任何层的组合。虽然设计为 .net 远程服务的网络共享可以安装在网络上的任何计算机上,并且客户端缓存可以自行发现,但它还没有完全实现。
缓存是通过接口 ICache<TKey,TValue> 访问的通用类。本地持久缓存使用 SQL Express Compact 4 创建即时数据库和表,这些表具有 TKey 的所有字段、时间戳和作为 Image 列序列化的 TValue。
在多层配置的情况下,当您在顶层缓存上使用 TryGetValue(TKey key, out TValue value) 方法时,如果第一层(内存缓存)没有该项,则会在下一层(本地持久缓存)内部检查,然后是下一层……直到没有更多的缓存可用于提供数据。当内存缓存丢弃一个项目时,它会让下一个缓存有机会将该项目添加到其层中,因此在持久缓存的情况下,数据将被存储以供未来请求使用。
缓存具有用户定义的保留时间参数(例如,内存缓存为几分钟,本地持久缓存为 30 天)和容量。
如果有人感兴趣,我可以将其发布为公共领域代码。

1

很高兴看到一个我之前没有考虑过的选项,而且即使它看起来是针对XML配置的,它也有等效的编程配置选项。然而,这不是我正在寻找的,因为它似乎没有提供基于内存使用限制的功能。通过对象计数限制缓存相当无用,因为这些对象可能是每个1KB或每个1GB消耗的树的根。 - Matt G

1

+1,因为这实际上是我两个月前阅读的文章,为设计我的自己提供了基础。我没有查看完整的源代码,但这篇文章是一个很好的起点。 - Matt G

0

它能在3.5上运行吗?看起来是4.0框架。 - Charles Byrne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接