Постоянный параллельный словарь в памяти в ASP.NET Core - PullRequest
1 голос
/ 22 апреля 2019

В приложении ASP.NET Core я хотел бы иметь постоянное общее состояние, аналогичное:

ConcurrentDictionary<string, Job> Jobs;

Различные компоненты приложений будут иметь доступ к этому общему состоянию (контроллеры обработки запросов, фоновые задачи), но моя главная проблема не в параллельном доступе. Что меня интересует, так это то, есть ли способ сохранить глобальную переменную, подобную этой, в течение всего времени жизни моего приложения ASP.NET Core.

Есть ли место, где я могу определить эту глобальную Jobs переменную, где она не будет уничтожена средой выполнения ASP.NET Core? Возможно, используя MemoryCache в некотором роде?

Использование чего-то вроде Redis, безусловно, будет работать, но мне любопытно, есть ли в ASP.NET Core надежное решение в памяти / в процессе для глобального общего состояния.

Ответы [ 2 ]

1 голос
/ 23 апреля 2019

Вы можете заключить в класс 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() {}
}
0 голосов
/ 22 апреля 2019

Запросите 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 подробности.Весь приведенный выше код взят с этой страницы.

Кэш-память, представленная здесь, представляет собой синглтон - один экземпляр кеша будет существовать на протяжении всего времени работы приложения.Но будьте внимательны, как только процесс завершится, все будет очищено.


Что касается вопроса "ну что, если мой кэш не имеет значения в тот момент, когда я его запрашиваю?"

Э-э, добро пожаловать в многопоточный код.Это просто факт жизни, промахи кеша - вещь.Это будет "" "" более "" "надежно, потому что весь цикл находится в памяти, но вы все равно должны принять это во внимание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...