为了账号安全,请及时绑定邮箱和手机立即绑定

ASP.NET Core 中的持久内存并发字典

ASP.NET Core 中的持久内存并发字典

C#
达令说 2022-12-24 12:27:31
在 ASP.NET Core 应用程序中,我希望拥有类似于以下内容的持久共享状态:ConcurrentDictionary<string, Job> Jobs;应用程序的各种组件将访问此共享状态(请求处理控制器、后台任务),但我主要关心的不是并发访问。我很好奇的是,是否有一种方法可以在我的 ASP.NET Core 应用程序的整个生命周期中保留这样的全局变量。有没有我可以定义这个全局Jobs变量的地方,它不会被 ASP.NET Core 运行时破坏?也许MemoryCache以某种方式利用?使用 Redis 之类的东西当然可以,但我很好奇 ASP.NET Core 中是否有针对全局共享状态的强大的内存中/进程中解决方案。
查看完整描述

3 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

您可以包装ConcurrentDictionary在一个类中并将其注册为单例。


public class SharedJobs

{

    private readonly ConcurrentDictionary<string, Job> _jobs

        = new ConcurrentDictionary<string, Job>();


    public ConcurrentDictionary<string, Job> Jobs => _jobs;

}

在 Startup.cs 中


services.AddSingleton<SharedJobs>();

用法


public class Service

{

    private readonly SharedJobs _shared;


    public Service(SharedJobs shared) => _shared = shared;


    public void DoSomething()

    {

        var job = _shared.Jobs.GetOrAdd("Key", new Job("New Job when not found"));

    }

}

您可以更进一步,隐藏您在幕后使用的事实,ConcurrentDictionary只向消费者公开所需的功能。


public class SharedJobs

{

    private readonly ConcurrentDictionary<string, Job> _jobs

        = new ConcurrentDictionary<string, Job>();


    public Job Get(string key)

    {

        return _jobs.GetOrAdd(key, CreateNewJob());

    }


    private Job CreateNewJob() {}

}


查看完整回答
反对 回复 2022-12-24
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

IMemoryCache在您的控制器/服务的构造函数中请求一个。


首先添加到您的启动以注册缓存服务:


public void ConfigureServices(IServiceCollection services)

{

    services.AddMemoryCache();


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

}

...在构造函数中请求它...


private IMemoryCache _cache;


public HomeController(IMemoryCache memoryCache)

{

    _cache = memoryCache;

}

...并使用它...


public IActionResult CacheTryGetValueSet()

{

    DateTime cacheEntry;


    // Look for cache key.

    if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))

    {

        // Key not in cache, so get data.

        cacheEntry = DateTime.Now;


        // Set cache options.

        var cacheEntryOptions = new MemoryCacheEntryOptions()

            // Keep in cache for this time, reset time if accessed.

            .SetSlidingExpiration(TimeSpan.FromSeconds(3));


        // Save data in cache.

        _cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);

    }


    return View("Cache", cacheEntry);

}

阅读 Microsoft 的ASP.NET Core 内存中缓存了解更多详细信息。以上所有代码均来自该页面。


这里提供的内存缓存是一个单例——缓存的单个实例将在应用程序的整个持续时间内存在。但请注意,一旦进程关闭,所有内容都会被清除。


至于“好吧,如果我的缓存在我要求的那一刻没有价值怎么办?”


呃,欢迎使用多线程代码。这只是生活中的事实,缓存未命中是一回事。它将变得“更”可靠,因为整个循环都在内存中,但您仍然需要考虑到这一点。


查看完整回答
反对 回复 2022-12-24
?
蓝山帝景

TA贡献1843条经验 获得超7个赞

IMemoryCache您可以使用AcroFS微型库在其之上使用持久层。它将首先尝试从内存加载数据,然后尝试从磁盘加载数据。


如果您在不同位置有多个项目,您可以为缓存文件夹设置一个绝对路径。


// set cache

_memoryCache.Persistent().Set(key, jobs);


// get cache

var found = _memoryCache.Persistent().TryGetValue(cacheKey, out jobs);


// get or create

var jobs = await _memoryCache.Persistent().GetOrCreate(cacheKey, async entry => await loadJobsAsync());


查看完整回答
反对 回复 2022-12-24
  • 3 回答
  • 0 关注
  • 180 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号