¿Estoy en lo cierto al pensar que este es el uso correcto de un diccionario concurrente?
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;
No tengo bloqueos, etc. y solo estoy actualizando el valor en el diccionario, aunque varios subprocesos pueden estar intentando hacer lo mismo.
newLongValue
depende del valor anterior demyDic[InputID]
?myDic[InputID]
por condición de carrera. Deberías intentarloGetOrAdd
myDic[InputID]
cause ningún problema cuando se usa como lvalue.GetOrAdd
no es un reemplazo correcto ya que agrega solo si el valor no existe. En su lugar, podemos usarAddOrUpdate
para agregar / actualizar el mismo valor en el diccionario.Respuestas:
Depende de lo que quieras decir con seguro para subprocesos.
Desde MSDN - Cómo: Agregar y quitar elementos de un ConcurrentDictionary :
Por lo tanto, es posible obtener una vista inconsistente del valor de un elemento en el diccionario.
fuente
La mejor forma de averiguarlo es consultar la documentación de MSDN.
Para ConcurrentDictionary, la página es http://msdn.microsoft.com/en-us/library/dd287191.aspx
En la sección de seguridad de subprocesos, se indica "Todos los miembros públicos y protegidos de ConcurrentDictionary (Of TKey, TValue) son seguros para subprocesos y pueden usarse simultáneamente desde varios subprocesos".
Entonces, desde el punto de vista de la concurrencia, estás bien.
fuente
Sí, tiene usted razón.
Eso y la posibilidad de enumerar el diccionario en un hilo mientras lo cambia en otro hilo son los únicos medios de existencia para esa clase.
fuente
ConcurrentDictionary
.Depende, en mi caso prefiero usar este método.
ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>);
Consulte MSDN Library para obtener detalles sobre el uso del método.
Uso de muestra:
results.AddOrUpdate( Id, id => new DbResult() { Id = id, Value = row.Value, Rank = 1 }, (id, v) => { v.Rank++; return v; });
fuente
Solo una nota: no justifica el uso de un objeto ConcurrentDicitonary con un bucle lineal, lo que lo hace infrautilizado. La mejor alternativa es seguir las recomendaciones de la Documentación de Microsoft, como menciona Oded usando Parallelism, de acuerdo con el siguiente ejemplo:
Parallel.For(0, 4, i => { myDic.TryAdd(i, 0); });
fuente