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;
}
}
처음에 내가 가정 : 키가 먼저 다음에 추가 될 때 예를 들어은 나도 thread가 외에, 다른 차단합니다 있는지 알고 싶습니다 예를 들어, 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 프레임 워크에 뭔가가 있습니까?
정확한 잠금은 무엇에 의존하고 있습니까? 나는 당신이 아직 성취하려는 것을 이해하지 못했습니다 ... –
Hey Jon. 나는 귀하의 명확한 요구를 이해하고 있는지 확신 할 수 없습니다. 나는 그것이 단어가 빠진 것이 틀림 없다고 확신하지만, 나는 어떤 것을 알아낼 수 없다. 내가 다시 말하려고합니다 : 다른 항목의 추가를 차단하거나 다른 키 값의 읽기 또는 바꾸기를 차단하지 않고 사전의 항목을 바꾸려고합니다. 위의 독점 코드에서'AccountCacheLock'으로 추가 한 추가 잠금 레이어가 필요합니까? 아니면 간단히'ConcurrentDictionary [key] ='를 호출 할 수 있습니까? – shannon
궁극적으로, 나는 자주 사용되는 계정 (및 하위) 정보에 대한 캐시를 계정 ID에 입력하기 만하려고합니다.나는 단순히 항목을 대체하기 위해 동시 사전을 요청하면 교체 기간 동안 모든 스레드가 캐시를 사용하지 못하도록 차단할 것입니다. – shannon