How to use MemoryCache insted of Timer to trigger a method?

旧巷老猫 提交于 2019-12-10 21:45:19

问题


The following method handle concurrent request by waiting the result of an already running operation.

Requests for data may come in simultaneously with same/different credentials. For each unique set of credentials there can be at most one GetCurrentInternal call in progress, with the result from that one call returned to all queued waiters when it is ready.

private readonly ConcurrentDictionary<Credentials, Lazy<Data>> _dataToCredentialMap =
        new ConcurrentDictionary<Credentials, Lazy<Data>>();

public virtual Data GetCurrent(Credentials credentials)
{
    if (credentials == null) { return GetCurrentInternal(null); }

    // It will only allow a single call to GetCurrentInternal, even if multiple threads query its Value property simultaneously.
    var lazyData = new Lazy<Data>(() => GetCurrentInternal(credentials));

    var data = _dataToCredentialMap.GetOrAdd(credentials, lazyData);
    return data.Value;
}

And I have added timer inside of this class in constructor. It's time-based invalidation policy where cache entries are auto-invalidated after a certain well-defined period of time.

_dataUpdateTimer = new Timer(UpdateData, null, TimeSpan.Zero, _dataUpdateInterval); // 1 min

Method that update data looks like the following:

private void UpdateData(object notUsed)
{
    try
    {
        foreach (var credential in _dataToCredentialMap.Keys)
        {
            var data = new Lazy<Data>(() => GetCurrent(credential));
            _dataToCredentialMap.AddOrUpdate(credential, data, (k, v) => data);
        }
     }
     catch (Exception ex)
     {
          _logger.WarnException(ex, "Failed to update agent metadata");
     }
}

I would like to use .Net MemoryCache class insted of my ConcurrentDictionary and Timer, to update my Credential and Data I think it will be more efficient.

I know how I can use MemoryCache instead of ConcurrentDictionary, but how can I call UpdateData each minute in constructor without a Timer?

Can you help me please how to do that?


回答1:


You can do this with MemoryCache without a Timer. Just set the CacheItemPolicy to AbsoluteExpiration:

MemoryCache memCache = MemoryCache.Default;
memCache.Add(<mykey>, <myvalue>,
          new CacheItemPolicy()
          {
            AbsoluteExpiration = DateTimeOffset.Now.Add(TimeSpan.FromMinutes(_expireminutes)),
            SlidingExpiration = new TimeSpan(0, 0, 0)
          }
          );


来源:https://stackoverflow.com/questions/34285365/how-to-use-memorycache-insted-of-timer-to-trigger-a-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!