如何使用Timer内存的Timer来触发方法?

时间:2015-12-15 09:25:52

标签: c# multithreading memorycache

以下方法通过等待已经运行的操作的结果来处理并发请求。

数据请求可能同时使用相同/不同的凭据。对于每个唯一的凭证集,最多只能进行一次GetCurrentInternal次呼叫,其中一次呼叫的结果在准备就绪时返回给所有排队的服务员。

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;
}

我在构造函数中添加了timer这个类。它是基于时间的失效策略,其中缓存条目在一段明确定义的时间段后自动失效。

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

更新数据的方法如下所示:

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");
     }
}

我想使用我MemoryCacheConcurrentDictionary的。Timer类来更新我的Credential and Data我认为它会更有效率。

我知道如何使用MemoryCache代替ConcurrentDictionary,但如何在没有UpdateData的构造函数中每分钟调用Timer

你能帮我解决一下吗?

1 个答案:

答案 0 :(得分:1)

您可以在没有Timer的情况下使用MemoryCache执行此操作。只需将CacheItemPolicy设置为AbsoluteExpiration:

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