Czy mam rację sądząc, że jest to właściwe użycie słownika współbieżnego
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;
Nie mam blokad itp. I właśnie aktualizuję wartość w słowniku, mimo że wiele wątków może próbować zrobić to samo.
newLongValue
zależy od poprzedniej wartościmyDic[InputID]
?myDic[InputID]
celu sprawdzenia stanu wyścigu. Powinieneś spróbowaćGetOrAdd
myDic[InputID]
powoduje to żaden problem, gdy jest używany jako lwartość.GetOrAdd
nie jest poprawnym zamiennikiem, ponieważ dodaje tylko wtedy, gdy wartość nie istnieje. Zamiast tego możemy użyć,AddOrUpdate
aby dodać / zaktualizować tę samą wartość w słowniku.Odpowiedzi:
To zależy od tego, co masz na myśli, mówiąc o bezpieczeństwie wątkowym.
Z MSDN - instrukcje : dodawanie i usuwanie elementów z ConcurrentDictionary :
W ten sposób można uzyskać niespójny widok wartości elementu w słowniku.
źródło
Najlepszym sposobem, aby się tego dowiedzieć, jest zapoznanie się z dokumentacją MSDN.
W przypadku ConcurrentDictionary strona to http://msdn.microsoft.com/en-us/library/dd287191.aspx
W sekcji dotyczącej bezpieczeństwa wątków znajduje się informacja: „Wszyscy publiczni i chronieni członkowie ConcurrentDictionary (Of TKey, TValue) są bezpieczni wątkowo i mogą być używane jednocześnie z wielu wątków”.
Więc z punktu widzenia współbieżności wszystko jest w porządku.
źródło
Tak masz rację.
To oraz możliwość wyliczenia słownika w jednym wątku podczas zmiany go w innym wątku to jedyne środki do istnienia dla tej klasy.
źródło
ConcurrentDictionary
.To zależy, w moim przypadku wolę tę metodę.
ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>);
Zobacz bibliotekę MSDN, aby uzyskać szczegółowe informacje dotyczące użycia metody.
Przykładowe użycie:
results.AddOrUpdate( Id, id => new DbResult() { Id = id, Value = row.Value, Rank = 1 }, (id, v) => { v.Rank++; return v; });
źródło
Tylko uwaga: nie uzasadnia używania obiektu ConcurrentDicitonary z pętlą liniową, co sprawia, że jest on niedostatecznie wykorzystywany. Najlepszą alternatywą jest postępowanie zgodnie z zaleceniami Dokumentacji Microsoft, o których wspomniał Oded używając Parallelism, zgodnie z poniższym przykładem:
Parallel.For(0, 4, i => { myDic.TryAdd(i, 0); });
źródło