Renverra-t-il uniquement false si le dictionnaire ne contient pas de valeur pour la clé donnée ou renverra-t-il également false en raison des conditions de concurrence du thread, comme un autre thread ajoute/met à jour quelque chose?
Question dans le code:
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);
Edit: Je pense que cela ne retournera false que s'il ne contient pas de valeur pour la clé donnée, mais je veux être absolument sûr.
Alors que Mitch a raison qu'un ConcurrentDictionary
n'est pas vulnérable aux conditions de concurrence, je pense que la réponse à la question que vous posez est que oui, si la clé est présente, TryRemove
fonctionnera et renverra true
.
Dans le code que vous avez publié, il n'y a aucun moyen que TryRemove
renvoie false
puisque cd
est une variable locale qui n'est accessible nulle part ailleurs. Mais si du code ailleurs a été référencé à cet objet ConcurrentDictionary
et a supprimé des clés sur un thread séparé, il est possible que TryRemove
puisse retourner false
, même ici - mais uniquement parce que la clé a déjà été supprimée , pas parce qu'une autre action est en cours d'exécution sur le dictionnaire et que la clé y est "bloquée".
Le ConcurrentDictionary ne souffre pas de conditions de course. C'est pourquoi vous l'utilisez.
Valeur de retour
true si un objet a été supprimé avec succès; sinon, faux.
Un autre point à souligner:
// This might fail if another thread is adding with key value of 1. cd.TryAdd(1, "one");
Ce commentaire est incorrect et souffre peut-être de la même idée fausse sur ce que signifie "essayer". Il ne s'agit pas d'une tentative d'ajout simultanée, c'est de savoir si une valeur a déjà été ajoutée avec la clé 1
.
Considérez une norme Dictionary<TKey,TValue>
. Le code équivalent serait:
if (!d.Contains(1))
d.Add(1, "one");
Cela nécessite deux opérations. Il n'y a aucun moyen de concevoir une telle API pour être threadsafe, car cd
peut avoir une valeur avec la clé 1
ajouté entre l'appel à Contains
et Add
, ce qui entraînerait alors le lancement de Add
.
Les collections simultanées ont des API qui regroupent logiquement ces paires test-et-do en opérations atomiques uniques, derrière une seule API.