以下方法通過等待已經運行的操作的結果來處理併發請求。如何使用內存緩存的定時器觸發一個方法?
數據請求可能與同一/不同憑據同時進入。對於每組唯一的憑證,最多隻能有一個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 MemoryCache
類insted的我ConcurrentDictionary
和Timer
,來更新我的Credential and Data
我認爲這將是更有效。
我知道如何使用MemoryCache
而不是ConcurrentDictionary
,但是如何在沒有Timer
的構造函數中每分鐘撥打UpdateData
?
你能幫我請怎麼做嗎?
只需使用Set/AddOrGetExisting()重載即可傳遞DateTimeOffset。 DTO指定物品何時被驅逐,您的計時器所做的同樣的事情。 –
MemoryCache不支持確保每個鍵只創建一個值。你現有的方法很好。 – usr
@usr所以我可以依靠'ConcurrentDictionary'只有一個線程可以'GetOrAdd'某個鍵/值,但是如果我將這一行更改爲MemoryCache.Default.AddOrGetExisting(...)它會是一個錯誤? – Anatoly