2011-11-22 2 views
58

를 잘 작성이 생각에 나는 오전 나는 등 어떤 잠금이없고 단지 여러 스레드가 시도 할 수있는 경우에도 사전에 값을 업데이트하고 동시 사전동시 사전 올바른 사용법

private ConcurrentDictionary<int,long> myDic = new ConcurrentDictionary<int,long>(); 

//Main thread at program startup 

for(int i = 0; i < 4; i++) 
{ 
    myDic.Add(i, 0); 
} 

//Seperate threads use this to update a value 

myDic[InputID] = newLongValue; 

의 올바른 사용이다 똑같이하십시오.

+2

상황에 따라 다르다 -'newLongValue'은'myDic [InputID]'의 이전 값에 의존 하는가? –

+74

"myDic"변수 이름에 대해 1UP! –

+2

당신은 경쟁 조건을 위해 키에 의해 직접'myDic [InputID]'에 접근하는 것을 피해야합니다. 당신은'GetOrAdd'를 시도해야합니다 –

답변

52

스레드 안전성의 의미에 달려 있습니다. MSDN에서

- How to: Add and Remove Items from a ConcurrentDictionary :

ConcurrentDictionary<TKey, TValue>은 멀티 스레드 시나리오를 위해 설계되었습니다. 컬렉션에서 항목을 추가하거나 제거하기 위해 코드에서 잠금을 사용할 필요가 없습니다. 그러나 한 스레드가 값을 검색하는 것이 항상 가능하며 다른 스레드는 동일한 키에 새 값을 제공하여 컬렉션을 즉시 업데이트 할 수 있습니다.

그래서, 사전의 항목의 값의 일관성 보기를 얻을 수 있습니다.

+1

그게 재미있는 점이야! 그 시나리오에서 여전히 자물쇠를 사용 하시겠습니까? – Jon

+0

@ 존 - 귀하의 신청서에 따라 다르며 괜찮습니까? 그러나 항목의 일관된보기를 원한다면 항목의 읽기 및 업데이트를 각각 자물쇠로 감쌀 필요가 있다고 말합니다. – Oded

+4

나는 이것이 의사가 말하는 것과 다르다고 생각한다. 불일치는보기에 포함 된 내용과 관련이 있습니다.보기가 값일 경우 완벽하게 일관됩니다.열쇠의 값을 얻는 한 사전의 키 값이 변경 될 수 있습니다. 이는 DateTime.Now 값과 일치하지 않습니다. –

2

네, 맞습니다.

다른 스레드에서 변경하는 동안 한 스레드에서 사전을 열거 할 수있는 가능성과 그 클래스에 대한 유일한 존재 방법입니다.

+7

내가 추가 할 내용은 [여기] (http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx)는 ' ConcurrentDictionary'. –

1

가장 좋은 방법은 MSDN 설명서를 확인하는 것입니다.

ConcurrentDictionary을 위해 웹 사이트는 스레드 안전 섹션에서 http://msdn.microsoft.com/en-us/library/dd287191.aspx

입니다, "(TKEY의, TValue) ConcurrentDictionary의 모든 공공 및 보호 된 멤버는 스레드 안전하며 여러 스레드에서 동시에 사용할 수있다."적혀있다

그래서 동시성 관점에서 당신은 괜찮습니다.

0

내 경우에는이 방법을 사용하는 것이 좋습니다.

ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>); 

자세한 방법은 MSDN Library을 참조하십시오.

샘플 사용 :

results.AddOrUpdate(
    Id, 
    id => new DbResult() { 
    Id = id, 
    Value = row.Value, 
    Rank = 1 
    }, 
    (id, v) => 
    { 
    v.Rank++; 
    return v; 
    }); 
+1

FYI : "(GetOrAdd 및 AddOrUpdate 메서드에) 값 팩토리 메서드를 제공하면 실제로 실행될 수 있으며 나중에 다른 스레드가이 레이스에서 우승했기 때문에 결과가 무시 될 수 있습니다." 자세한 정보는 여기에 있습니다 : https://arbel.net/2013/02/03/best-practices-for-using-concurrentdictionary/ – keremispirli

+0

예, 맞습니다, 비고 섹션에서 언급했듯이 "AddOrUpdate를 동시에 호출하면 addValueFactory는 다른 스레드에서 여러 번 호출 될 수 있지만 키/값 쌍이 모든 호출에 대해 사전에 추가되지 않을 수 있습니다. " 따라서 여러 개의 영구 객체를 생성하지 않아야합니다. – Onur

+0

그리고 이전에 추가 된 객체의 속성을 변경하는 것과 같이 저장된 객체를 완전히 변경하지 않고 내용을 업데이트해야하는 경우이 방법이 유용합니다. 그렇지 않으면 잠금 또는 기타 동기화 방법을 사용해야합니다. – Onur

관련 문제