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

时间:2019-04-22 20:20:05

标签: c# asp.net-core .net-core

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

ConcurrentDictionary<string, Job> Jobs;

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

是否有地方可以定义此全局Jobs变量,而不会被ASP.NET Core运行时破坏?也许以某种方式利用MemoryCache

使用类似Redis的方法肯定可以工作,但是我很好奇ASP.NET Core中是否存在针对全局共享状态的强大的内存/进程内解决方案。

2 个答案:

答案 0 :(得分:1)

您可以将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() {}
}

答案 1 :(得分:0)

在控制器的/服务的构造函数中询问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的Cache in-memory in ASP.NET Core。以上所有代码均来自该页面。

此处提供的内存缓存是一个Singleton-在应用程序的整个过程中,缓存的单个实例将存在。不过请注意,一旦该进程关闭,一切都会清除。


关于关注点“如果我的缓存现在没有该值,该怎么办?”

嗯,欢迎使用多线程代码。这只是生活中的事实,缓存丢失是一回事。因为整个周期都在内存中,所以它将“可靠”可靠,但是您仍然需要考虑到这一点。