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

在 ASP.NET Core 应用程序中,我希望拥有类似于以下内容的持久共享状态:

ConcurrentDictionary<string, Job> Jobs;

应用程序的各种组件将访问此共享状态(请求处理控制器、后台任务),但我主要关心的不是并发访问。我很好奇的是,是否有一种方法可以在我的 ASP.NET Core 应用程序的整个生命周期中保留这样的全局变量。

有没有我可以定义这个全局Jobs变量的地方,它不会被 ASP.NET Core 运行时破坏?也许MemoryCache以某种方式利用?

使用 Redis 之类的东西当然可以,但我很好奇 ASP.NET Core 中是否有针对全局共享状态的强大的内存中/进程中解决方案。


达令说
浏览 287回答 3
3回答

侃侃无极

您可以包装ConcurrentDictionary在一个类中并将其注册为单例。public class SharedJobs{&nbsp; &nbsp; private readonly ConcurrentDictionary<string, Job> _jobs&nbsp; &nbsp; &nbsp; &nbsp; = new ConcurrentDictionary<string, Job>();&nbsp; &nbsp; public ConcurrentDictionary<string, Job> Jobs => _jobs;}在 Startup.cs 中services.AddSingleton<SharedJobs>();用法public class Service{&nbsp; &nbsp; private readonly SharedJobs _shared;&nbsp; &nbsp; public Service(SharedJobs shared) => _shared = shared;&nbsp; &nbsp; public void DoSomething()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var job = _shared.Jobs.GetOrAdd("Key", new Job("New Job when not found"));&nbsp; &nbsp; }}您可以更进一步,隐藏您在幕后使用的事实,ConcurrentDictionary只向消费者公开所需的功能。public class SharedJobs{&nbsp; &nbsp; private readonly ConcurrentDictionary<string, Job> _jobs&nbsp; &nbsp; &nbsp; &nbsp; = new ConcurrentDictionary<string, Job>();&nbsp; &nbsp; public Job Get(string key)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return _jobs.GetOrAdd(key, CreateNewJob());&nbsp; &nbsp; }&nbsp; &nbsp; private Job CreateNewJob() {}}

蝴蝶刀刀

IMemoryCache在您的控制器/服务的构造函数中请求一个。首先添加到您的启动以注册缓存服务:public void ConfigureServices(IServiceCollection services){&nbsp; &nbsp; services.AddMemoryCache();&nbsp; &nbsp; services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}...在构造函数中请求它...private IMemoryCache _cache;public HomeController(IMemoryCache memoryCache){&nbsp; &nbsp; _cache = memoryCache;}...并使用它...public IActionResult CacheTryGetValueSet(){&nbsp; &nbsp; DateTime cacheEntry;&nbsp; &nbsp; // Look for cache key.&nbsp; &nbsp; if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // Key not in cache, so get data.&nbsp; &nbsp; &nbsp; &nbsp; cacheEntry = DateTime.Now;&nbsp; &nbsp; &nbsp; &nbsp; // Set cache options.&nbsp; &nbsp; &nbsp; &nbsp; var cacheEntryOptions = new MemoryCacheEntryOptions()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Keep in cache for this time, reset time if accessed.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .SetSlidingExpiration(TimeSpan.FromSeconds(3));&nbsp; &nbsp; &nbsp; &nbsp; // Save data in cache.&nbsp; &nbsp; &nbsp; &nbsp; _cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);&nbsp; &nbsp; }&nbsp; &nbsp; return View("Cache", cacheEntry);}阅读 Microsoft 的ASP.NET Core 内存中缓存了解更多详细信息。以上所有代码均来自该页面。这里提供的内存缓存是一个单例——缓存的单个实例将在应用程序的整个持续时间内存在。但请注意,一旦进程关闭,所有内容都会被清除。至于“好吧,如果我的缓存在我要求的那一刻没有价值怎么办?”呃,欢迎使用多线程代码。这只是生活中的事实,缓存未命中是一回事。它将变得“更”可靠,因为整个循环都在内存中,但您仍然需要考虑到这一点。

蓝山帝景

IMemoryCache您可以使用AcroFS微型库在其之上使用持久层。它将首先尝试从内存加载数据,然后尝试从磁盘加载数据。如果您在不同位置有多个项目,您可以为缓存文件夹设置一个绝对路径。// set cache_memoryCache.Persistent().Set(key, jobs);// get cachevar found = _memoryCache.Persistent().TryGetValue(cacheKey, out jobs);// get or createvar jobs = await _memoryCache.Persistent().GetOrCreate(cacheKey, async entry => await loadJobsAsync());
打开App,查看更多内容
随时随地看视频慕课网APP