gpt4 book ai didi

.net - .NET 的线程安全缓存库

转载 作者:行者123 更新时间:2023-12-03 08:58:52 24 4
gpt4 key购买 nike

背景:

我维护了几个可以或已经从缓存中受益的 Winforms 应用程序和类库。我也知道 Caching Application BlockSystem.Web.Caching命名空间(根据我收集到的信息,它完全可以在 ASP.NET 之外使用)。

我发现,尽管上述两个类在技术上都是“线程安全的”,因为各个方法是同步的,但它们似乎并没有真正为多线程场景设计得特别好。具体来说,他们没有实现 GetOrAdd method类似于新的 ConcurrentDictionary 中的那个.NET 4.0 中的类。

我认为这种方法是缓存/查找功能的原始方法,显然框架设计者也意识到了这一点——这就是这些方法存在于并发集合中的原因。然而,除了我还没有在生产应用程序中使用 .NET 4.0 之外,字典并不是一个成熟的缓存——它没有过期、持久/分布式存储等功能。

为什么这很重要:

“富客户端”应用程序(甚至某些 Web 应用程序)中一个相当典型的设计是在应用程序启动时开始预加载缓存,如果客户端请求尚未加载的数据则阻塞(随后缓存它以备将来使用)采用)。如果用户正在快速完成他的工作流程,或者如果网络连接很慢,那么客户端与预加载器竞争的情况并不少见,两次请求相同的数据确实没有多大意义,尤其是在请求相对昂贵的情况下。

所以我似乎还有一些同样糟糕的选择:

  • 根本不要尝试使操作原子化,并冒着数据被加载两次的风险(并且可能有两个不同的线程在不同的副本上运行);
  • 序列化对缓存的访问,这意味着锁定整个缓存只是为了加载单个项目;
  • 开始重新发明轮子只是为了获得一些额外的方法。


  • 澄清:示例时间线

    假设当一个应用程序启动时,它需要加载 3 个数据集,每个数据集需要 10 秒才能加载。考虑以下两个时间线:

    00:00 - 开始加载数据集 1
    00:10 - 开始加载数据集 2
    00:19 - 用户请求数据集 2

    在上述情况下,如果我们不使用任何类型的同步,用户必须等待整整 10 秒才能获得 1 秒后可用的数据,因为代码会看到该项目尚未加载到缓存中并尝试重新加载它。

    00:00 - 开始加载数据集 1
    00:10 - 开始加载数据集 2
    00:11 - 用户请求数据集 1

    在这种情况下,用户正在请求已经是 的数据。在 缓存。但是如果我们序列化对缓存的访问,他将不得不再等待 9 秒,因为缓存管理器(不管是什么)不知道被请求的特定项目,只有“某事”是被请求并且“某事”正在进行中。

    问题:

    是否有任何适用于 .NET(4.0 之前)的缓存库 实现这样的原子操作,正如人们对线程安全缓存所期望的那样?

    或者,是否有一些方法可以扩展现有的“线程安全”缓存以支持此类操作, 没有 序列化对缓存的访问(这会破坏首先使用线程安全实现的目的)?我怀疑是否存在,但也许我只是累了而忽略了一个明显的解决方法。

    或者......我还有什么遗漏的吗?如果两个竞争线程碰巧都在第一次或过期后同时请求相同的项目,这只是标准做法吗?

    最佳答案

    我实现了一个名为 MemoryCacheT 的简单库。它在 GitHubNuGet .它基本上将项目存储在 ConcurrentDictionary 中,您可以在添加项目时指定过期策略。欢迎任何反馈、评论、建议。

    关于.net - .NET 的线程安全缓存库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2330275/

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