Kiedy ConcurrentDictionary TryRemove zwróci wartość false


79

Czy zwróci fałsz tylko wtedy, gdy słownik nie zawiera wartości dla danego klucza, czy też zwróci fałsz z powodu warunków wyścigu wątków, tak jak inny wątek coś dodaje / aktualizuje?

Pytanie w kodzie:

ConcurrentDictionary<int, string> cd = new ConcurrentDictionary<int, string>();

// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one"); 

// Will this ever fail if no other thread ever removes with the key value of 1?
cd.TryRemove(1); 

Edycja: Myślę, że zwróci false tylko wtedy, gdy nie zawiera wartości dla danego klucza, ale chcesz być absolutnie pewien.

Odpowiedzi:


85

Chociaż Mitch ma rację, że a ConcurrentDictionarynie jest podatny na warunki wyścigu, myślę, że odpowiedź na pytanie, które zadajesz, brzmi: tak, jeśli klucz jest obecny, TryRemovezadziała i powróci true.

W opublikowanym kodzie nie ma możliwości TryRemovepowrotu, falseponieważ cdjest to zmienna lokalna, do której nie można uzyskać dostępu nigdzie indziej. Ale jeśli jakiś kod w innym miejscu miałby odniesienie do tego ConcurrentDictionaryobiektu i usuwał klucze w oddzielnym wątku, to możliwe, że TryRemovemoże powrócić false, nawet tutaj - ale tylko dlatego, że klucz został już usunięty , a nie dlatego, że wykonywana jest inna akcja słownik i klucz jakoś tam „utknęły”.



2

Jeszcze jedna uwaga:

// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one"); 

Ten komentarz jest niepoprawny i prawdopodobnie zawiera to samo błędne przekonanie, co to znaczy „spróbować”. Nie chodzi o jednoczesną próbę dodania, chodzi o to, czy wartość została już dodana za pomocą klucza 1.

Rozważ standard Dictionary<TKey,TValue>. Odpowiedni kod to:

if (!d.Contains(1))
    d.Add(1, "one");

Wymaga to dwóch operacji. Nie ma możliwości zaprojektowania takiego interfejsu API, aby był bezpieczny dla wątków, ponieważ cdmoże mieć wartość z kluczem 1dodanym między wywołaniem do Containsi Add, co spowodowałoby Addrzucanie.

Współbieżne kolekcje mają interfejsy API, które logicznie łączą te pary test i wykonaj w pojedyncze operacje atomowe za jednym interfejsem API.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.