tpl threading thread programming programing parallel net c# .net concurrency

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í.