下面的方法通过等待已经运行的操作的结果来处理并发请求。
对数据的请求可以以相同/不同的凭据同时发出。对于每个唯一的凭证集,最多可以有一个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");
}
}
我想在我的.Net和Timer
中使用MemoryCache
类,来更新我的Credential and Data
--我认为它会更高效。
我知道如何使用MemoryCache
而不是ConcurrentDictionary
,但在构造函数中,如何在没有Timer
的情况下每分钟调用UpdateData
你能帮我怎么做吗?
发布于 2015-12-15 02:26:41
您可以在没有计时器的情况下使用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)
}
);
https://stackoverflow.com/questions/34285365
复制相似问题