당신이 할 수있는 컴파일러 오류를 수정하기를 : 당신이 잠재적으로하지 스레드 안전 여러 스레드에서 HashSet
에 추가 할 수 있도록 "업데이트"기능은 어떤 잠금 내에서 실행되지 않기 때문에
myDic.AddOrUpdate(1, new HashSet<int>() { myFirstElement },
(key, actualValue) => {
actualValue.Add(myFirstElement);
return actualValue;
});
하지만이, 스레드로부터 안전하지 않습니다. 예를 들어 값이 손실 될 수 있습니다. 따라서 HashSet
에 1000 개의 항목을 추가했지만 결국에는 970 개의 항목 만 남았습니다. AddOrUpdate
의 업데이트 기능에는 부작용이 없어야하며 여기에 설명되어 있습니다.
myDic.AddOrUpdate(1, new HashSet<int>() { myFirstElement },
(key, actualValue) => {
lock (actualValue) {
actualValue.Add(myFirstElement);
return actualValue;
}
});
를하지만 처음에 잠금이없는 구조 (ConcurrentDictionary
)를 사용하는 이유는 다음 질문은
당신은 HashSet
에 값을 추가하는 자신을 통해 잠글 수 있습니다. 게다가 다른 코드는 사전에서 HashSet
을 얻고 자물쇠없이 값을 추가하여 모든 것을 쓸모 없게 만들 수 있습니다. 따라서 어떤 이유로 든 그렇게하기로 결정한 경우 - 해당 코드에서 HashSet
에 액세스 할 때 모든 코드가 잠겨 있는지 확인해야합니다.
대신에 HashSet
대신 동시 수집을 사용하십시오. 내가 아는 한 ConcurrentHashSet
은 존재하지 않지만 대체 키로 다른 ConcurrentDictionary
을 사용할 수도 있습니다 (또는 사용자 정의 구현을 위해 인터넷을 살펴보십시오).
사이드 노트. 키가 이미 있기 때문에 그 사전이 필요하지 않은 경우에도, AddOrUpdate
를 호출 할 때 다음
myDic.AddOrUpdate(1, new Hashset<int>(){myFirstElement},
당신은 새로운 HashSet
마다 시간을 만들 수 있습니다.대신 값 추가 공장 오버로드를 사용
myDic.AddOrUpdate(1, (key) => new HashSet<int>() { myFirstElement },
편집 : ConcurrentDictionary
의 샘플 사용을 해시 세트로 :
var myDic = new ConcurrentDictionary<long, ConcurrentDictionary<int, byte>>();
long key = 1;
int element = 1;
var hashSet = myDic.AddOrUpdate(key,
_ => new ConcurrentDictionary<int, byte>(new[] {new KeyValuePair<int, byte>(element, 0)}),
(_, oldValue) => {
oldValue.TryAdd(element, 0);
return oldValue;
});
이 팁 주셔서 너무 감사드립니다. 예를 들어, 더미 키를 사용하여 CouncurrentDictionary를 값으로 사용할 수있는 방법을 보여줄 수 있습니까? 감사. –
@ ÁlvaroGarcía 업데이트 대답 예 – Evk
이 예제에서. 내가 해시 세트를 얻고 새 요소를 추가하려고하면 누군가가이를 삭제할 수 있으므로 추가하려고 할 때 오류가 발생할 수 있습니다. 또는 최소한 사전에없는 해트트에 요소를 추가합니다. . 맞습니까? –