替換與ConcurrentDictionary關鍵字關聯的值是否會鎖定超出該關鍵字的任何字典操作?在不同的ConcurrentDictionary鍵上替換操作是否共享一個鎖?
編輯:例如,我想知道這兩個線程將阻止其他的,除了當鍵首先添加,如下所示:
public static class Test {
private static ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>();
public static Test() {
new Thread(UpdateItem1).Start();
new Thread(UpdateItem2).Start();
}
private static void UpdateItem1() {
while (true) cd[1] = 0;
}
private static void UpdateItem2() {
while (true) cd[2] = 0;
}
}
起初我以爲這確實如此,因爲例如dictionary[key] = value;
可能指的是還沒有出現的密鑰。然而,在工作時,我意識到如果需要添加,它可能會在單獨的鎖升級後發生。
我在起草以下班級,但如果對上述問題的答案是「否」,那麼AccountCacheLock
班級提供的間接性是不必要的。事實上,我所有的鎖管理都是不必要的。
// A flattened subset of repository user values that are referenced for every member page access
public class AccountCache {
// The AccountCacheLock wrapper allows the AccountCache item to be updated in a locally-confined account-specific lock.
// Otherwise, one of the following would be necessary:
// Replace a ConcurrentDictionary item, requiring a lock on the ConcurrentDictionary object (unless the ConcurrentDictionary internally implements similar indirection)
// Update the contents of the AccountCache item, requiring either a copy to be returned or the lock to wrap the caller's use of it.
private static readonly ConcurrentDictionary<int, AccountCacheLock> dictionary = new ConcurrentDictionary<int, AccountCacheLock>();
public static AccountCache Get(int accountId, SiteEntities refreshSource) {
AccountCacheLock accountCacheLock = dictionary.GetOrAdd(accountId, k => new AccountCacheLock());
AccountCache accountCache;
lock (accountCacheLock) {
accountCache = accountCacheLock.AccountCache;
}
if (accountCache == null || accountCache.ExpiresOn < DateTime.UtcNow) {
accountCache = new AccountCache(refreshSource.Accounts.Single(a => a.Id == accountId));
lock (accountCacheLock) {
accountCacheLock.AccountCache = accountCache;
}
}
return accountCache;
}
public static void Invalidate(int accountId) {
// TODO
}
private AccountCache(Account account) {
ExpiresOn = DateTime.UtcNow.AddHours(1);
Status = account.Status;
CommunityRole = account.CommunityRole;
Email = account.Email;
}
public readonly DateTime ExpiresOn;
public readonly AccountStates Status;
public readonly CommunityRoles CommunityRole;
public readonly string Email;
private class AccountCacheLock {
public AccountCache AccountCache;
}
}
旁邊的問題:有沒有什麼在ASP.NET框架已經這樣做?
什麼確切的鎖定將依靠?我還不完全明白你想要達到什麼目標...... –
嘿喬恩。我不確定我是否理解你的澄清要求;我很確定它缺少一個詞,但我無法弄清楚它是什麼。我會嘗試重申:我正在尋找替換字典中的項目,而不阻止添加其他項目,或阻止讀取或替換其他鍵控值。我是否需要在我上面的專有代碼中使用'AccountCacheLock'添加的額外鎖定層,或者我可以簡單地調用'ConcurrentDictionary [key] ='? – shannon
最終,我只是試圖爲帳戶ID上鍵入的常用帳戶(和子)信息創建緩存。我擔心,如果我只是要求併發字典替換一個項目,我會在替換期間阻止所有線程使用緩存。 – shannon