c# - threading - Cuándo será ConcurrentDictionary TryRemove falso
thread programming c# (3)
El ConcurrentDictionary no sufre de condiciones de carrera. Es por eso que lo usas.
Valor de retorno
verdadero si un objeto fue eliminado con éxito; de lo contrario, falso.
¿Devolverá falso solamente si el diccionario no contiene un valor para la clave dada o también devolverá falso debido a las condiciones de carrera de subprocesos, como otro hilo agrega / actualiza algo?
Pregunta en el código:
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);
Editar: creo que solo devolverá falso si no contiene un valor para la clave dada, pero quiere estar absolutamente seguro.
Otro punto para hacer:
// This might fail if another thread is adding with key value of 1. cd.TryAdd(1, "one");
Este comentario es incorrecto y posiblemente adolece del mismo concepto erróneo sobre lo que significa "probar". No se trata de un intento simultáneo de agregar, es si ya se agregó un valor con la clave 1
.
Considere un Dictionary<TKey,TValue>
estándar Dictionary<TKey,TValue>
. El código equivalente sería:
if (!d.Contains(1))
d.Add(1, "one");
Esto requiere dos operaciones. No hay forma de diseñar dicha API para que sea segura, ya que el cd
podría tener un valor con la clave 1
agregada entre la llamada a Contains
y Add
, lo que daría como resultado Add
arrojando.
Las colecciones concurrentes tienen API que lógicamente agrupan estos pares de prueba y acción en operaciones atómicas individuales, detrás de una sola API.
Si bien Mitch tiene razón en que un ConcurrentDictionary
no es vulnerable a las condiciones de carrera, creo que la respuesta a la pregunta que hace es que sí, si la clave está presente, TryRemove
funcionará y será true
.
En el código que publicaste, no hay forma de que TryRemove
devuelva false
ya que cd
es una variable local a la que no se accede desde ningún otro lado. Pero si a algún código en otro lugar se le hubiera dado una referencia a este objeto ConcurrentDictionary
y estuviera eliminando claves en un hilo separado, entonces es posible que TryRemove
pueda devolver false
, incluso aquí, pero solo porque la clave ya se eliminó , no porque haya alguna otra acción se realiza en el diccionario y la clave está de alguna manera "estancada" allí.