C# 生产质量线程安全内存中 LRU 缓存是否过期?

2024-02-22

这也许就像求棒上的月亮一样;但是是否有“C# 生产质量的线程安全内存中 LRU 缓存(带过期)?或者有人有最佳实践想法来实现同样的事情吗?

(LRU 是“最近最少使用”-http://en.wikipedia.org/wiki/Cache_algorithms#LRU http://en.wikipedia.org/wiki/Cache_algorithms#LRU)

澄清一下:我想通过以下接口支持 ASP.Net MVC 站点中的内存缓存:

public interface ICache
{
    T GetOrAdd<T>(string key, Func<T> create, TimeSpan timeToLive) where T : class;
    bool Remove(string key);
}
  • 我想要“GetOrAdd”,因为我希望这些操作是“原子的” - 即避免两个线程尝试同时查询缓存的竞争条件
  • 我想要 Create 函数,因为创建这些对象的成本很高(需要复杂的数据库访问)
  • 我需要过期,因为这些对象在一段时间后就会过期

Microsoft 的最佳解决方案似乎是“System.Runtime.Caching.MemoryCache”,但它似乎有一些警告:

  • 它需要定期轮询缓存以遵守施加的内存限制。我的系统不可能出现内存不足的情况。我读过这篇文章,这让我很担心:MemoryCache 不遵守配置中的内存限制 https://stackoverflow.com/questions/6895956/memorycache-does-not-obey-memory-limits-in-configuration
  • 它似乎只有“AddOrGetExisting”来支持我的界面,它将构造的对象作为第二个参数 - 如果这个对象的创建成本很高,那么预先构造它不会有点破坏缓存的意义吗?

代码看起来像这样:

public sealed class Cache : ICache
{
    private readonly MemoryCache _cache;

    public Cache()
    {
        _cache = MemoryCache.Default;
    }

    public T GetOrAdd<T>(string key, Func<T> create, TimeSpan timeToLive) where T : class
    {
        // This call kinda defeats the point of the cache ?!?
        var newValue = create();

        return _cache.AddOrGetExisting(key, newValue, DateTimeOffset.UtcNow + timeToLive) as T;
    }

    public bool Remove(string key)
    {
        _cache.Remove(key);
        return true;
    }
}

或者也许 Lazy 周围有更好的东西,它确实允许只创建一次结果,但感觉像是一个黑客(缓存 Func 有后果吗?):

class Program
{
    static void Main(string[] args)
    {
        Func<Foo> creation = () =>
        {
            // Some expensive thing
            return new Foo();
        };

        Cache cache = new Cache();
        // Result 1 and 2 are correctly the same instance. Result 3 is correctly a new instance...
        var result1 = cache.GetOrAdd("myKey", creation, TimeSpan.FromMinutes(30));
        var result2 = cache.GetOrAdd("myKey", creation, TimeSpan.FromMinutes(30));
        var result3 = cache.GetOrAdd("myKey3", creation, TimeSpan.FromMinutes(30));

        return;
    }
}

public sealed class Foo
{
    private static int Counter = 0;
    private int Index = 0;

    public Foo()
    {
        Index = ++Counter;
    }
}

public sealed class Cache
{
    private readonly MemoryCache _cache;

    public Cache()
    {
        _cache = MemoryCache.Default;
    }

    public T GetOrAdd<T>(string key, Func<T> create, TimeSpan timeToLive) where T : class
    {
        var newValue = new Lazy<T>(create, LazyThreadSafetyMode.PublicationOnly);
        var value = (Lazy<T>)_cache.AddOrGetExisting(key, newValue, DateTimeOffset.UtcNow + timeToLive);
        return (value ?? newValue).Value;
    }

    public bool Remove(string key)
    {
        _cache.Remove(key);
        return true;
    }
}

其他想法:

  • 我也找到了这个实现,但它不允许您指定基于时间的到期日:IDictionary 是否有 LRU 实现? https://stackoverflow.com/questions/754233/is-it-there-any-lru-implementation-of-idictionary
  • 也许有一个使用 ReaderWriterLock 的实现?
  • ConcurrentDictionary 的一些包装?

我实现了一个专为并发工作负载设计的线程安全伪 LRU - 目前在生产系统中使用。性能非常接近 ConcurrentDictionary,比 MemoryCache 快大约 10 倍,并且命中率比传统 LRU 更好。下面的 github 链接提供了完整的分析。

用法如下:

int capacity = 666;
var lru = new ConcurrentTLru<int, SomeItem>(capacity, TimeSpan.FromMinutes(5));

var value = lru.GetOrAdd(1, (k) => new SomeItem(k));
bool removed = lru.TryRemove(1);

GitHub: https://github.com/bitfaster/BitFaster.Caching https://github.com/bitfaster/BitFaster.Caching

Install-Package BitFaster.Caching
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 生产质量线程安全内存中 LRU 缓存是否过期? 的相关文章

随机推荐

  • React Native 0.62.2 外观返回错误的配色方案

    在 iOS 模拟器 13 3 和 Android 10 上 我有一个问题Appearance and useColorScheme当我设置黑暗模式时 它仍然返回 亮 import useColorScheme Appearance from
  • ActivityRecord 的活动空闲超时

    所以我有一个奇怪的问题 我不完全确定我应该提供哪些所有信息 但我会尽力 如果我需要添加更多信息 请告诉我 我遇到一个问题 当我完成我的Activity并返回到上一个Activity 或者用新的启动它Intent 问题似乎集中在完成Activ
  • 在 Windows Phone 7 上从独立存储打开 JPEG 时出现问题

    Scenario 应用程序打开 检查隔离存储中是否存在背景图像 如果没有 从网络下载 并将其保存到独立存储 从独立存储加载图像并将其设置为全景控件上的背景 Problem 图像未在 GUI 中加载 当我检查从独立存储接收的字节数组时 它包含
  • Javascript 困境:创建荧光笔工具……快完成了

    我正在开发一个小 JS 插件 我希望它的功能与真正的荧光笔完全一样 取一个标准的 html 文本 div 带有子元素 用鼠标选择文本 并在鼠标松开时保持突出显示不变 看起来相当简单 对吧 这是我到目前为止所拥有的 http efflux u
  • NewtonSoft.Json 序列化和反序列化具有 IEnumerable 类型属性的类

    我正在尝试移动一些代码来使用 ASP NET MVC Web API 生成的 Json 数据而不是 SOAP Xml 我遇到了序列化和反序列化类型属性的问题 IEnumerable
  • iOS:如何获取长按手势的持续时间?

    我正在开发一款游戏 其中游戏对象的属性是通过长按对象本身来设置的 该属性的值由长按手势的持续时间决定 我正在使用 UILongPressGestureRecognizer 来实现此目的 所以它是这样的 gameObjectView addG
  • Eclipse、Scala 和 Maven - 未生成类文件

    我在 Eclipse 中将我的 scala 项目转换为使用 Maven 只需右键单击项目并配置 Maven 构建 这创建了 pom xml 添加了正确的依赖项 从 Maven 存储库中提取所需的 jar 但每当我尝试编译时 我不会请参阅 t
  • Laravel - Collection::delete 方法不存在

    我正在尝试测试 boot static deleting 方法 该方法应该在通过 Eloquent 删除模型时触发 Tinker 中的命令App User find 6 gt delete 返回 方法 Collection delete 不
  • 迭代哈希在 Python 和 Java 中返回不同的值

    我正在尝试将 python 2 7 脚本移植到 Java 它多次迭代 sha256 哈希 但最终得到不同的结果 我注意到他们第一次返回相同的结果 但从那时起它就不同了 这是 Python 实现 import hashlib def to h
  • Windows 窗体的多个滑块轨迹栏

    有谁知道如何在 WinForms 中创建带有多个滑块的跟踪栏 我想标记一个范围 另外 是否可以将滑块垂直偏移一点 我的目标是在轨迹栏上方有两个滑块 在轨迹栏下方有两个滑块 v v 您可以通过编写自己的代码来做到这一点UserControl您
  • 使用 bootstrap 主题从链接添加自定义类到 drupal-modal drupal 8

    在 Drupal 8 中 当您使用以下命令创建链接时使用引导主题class and data dialog type属性如下面的代码 a class use ajax href http drupal page front text a 您
  • 我可以在C#中反序列化包含0.0的JSON字符串吗?

    我从 Web 服务返回的 JSON 有一个整数 错误地表示为 0 0 我的反序列化代码如下所示 var serializer new JsonSerializer var ret serializer Deserialize
  • 使用 R 将多个文件从多个文件夹复制到单个文件夹

    嘿我想问如何使用R语言将多个文件夹中的多个文件复制到单个文件夹 假设有三个文件夹 桌面 文件夹 A 任务 子任务 桌面 文件夹 B 任务 子任务 桌面 folder C 任务 子任务 每个sub task文件夹中都有多个文件 我想复制 su
  • Microsoft Teams 中的 ActionTypes.MessageBack 存在问题?

    我正在使用带有 C 的 Bot Builder 3 11 版本 我有一个 ActionTypes MessageBack 类型的操作按钮 具有以下属性 cardActions Add new CardAction Type ActionTy
  • CSS !important 声明在 Outlook 2007 中不起作用

    我想创建一个锚颜色为红色的电子邮件模板 它应该是 重要的声明以避免继承其他样式值 不幸的是 它在 Outlook 2007 2010 中无法正确呈现 有人有类似的经历吗 与 Outlook 中的 important 标记支持相关的问题 我在
  • 如何同步两个View的drawable状态

    在 Android 中 我有一个 EditText 和一个位于 EditText 旁边的按钮 每当我按下一个按钮时 我都希望另一个也以相同的状态出现 我尝试将 android clickable true 放在封闭布局上 将 android
  • 对角化符号矩阵

    我需要用 python 对角化一个符号矩阵 在 Mathematica 中这可以很容易地完成 但是当使用模块时numpy linalg我遇到问题 为了具体起见 请考虑矩阵 2 x x 3 where x是一个符号变量 我想我遇到了问题 因为
  • 为 UIFont 定义宏不起作用

    我想定义一个宏来统一我的应用程序中的所有字体 define EXO REGULAR FONT size UIFont fontWithName Exo Regular size size 而不是像这样使用这个宏 myLabel font E
  • 如何在 Espresso 中的 RecyclerView 内部断言?

    我正在使用 espresso contrib 来执行操作RecyclerView 并且它应该正常工作 例如 click on first item onView withId R id recycler view perform Recyc
  • C# 生产质量线程安全内存中 LRU 缓存是否过期?

    这也许就像求棒上的月亮一样 但是是否有 C 生产质量的线程安全内存中 LRU 缓存 带过期 或者有人有最佳实践想法来实现同样的事情吗 LRU 是 最近最少使用 http en wikipedia org wiki Cache algorit