Saltando de this thread, estoy tratando de utilizar ConcurrentDictionary para replicar el siguiente:.NET4.0: Actualización Hilo de seguridad de ConcurrentDictionary <TKey, TValue>
public static class Tracker
{
private static Dictionary<string, int> foo = new Dictionary<string, int>();
private static object myLock = new object();
public static void Add(string bar)
{
lock(myLock)
{
if (!foo.ContainsKey(bar))
foo.Add(bar, 0);
foo[bar] = foo[bar] + 1;
}
}
public static void Remove(string bar)
{
lock(myLock)
{
if (foo.ContainsKey(bar))
{
if (foo[bar] > 0)
foo[bar] = foo[bar] - 1;
}
}
}
}
Mi intento inicial es:
public static class Tracker2
{
private static ConcurrentDictionary<string, int> foo =
new ConcurrentDictionary<string, int>();
public static void Add(string bar)
{
foo.AddOrUpdate(bar, 1, (key, n) => n + 1);
}
public static void Remove(string bar)
{
// Adding a 0'd item may be ok if it wasn't there for some reason,
// but it's not identical to the above Remove() implementation.
foo.AddOrUpdate(bar, 0, (key, n) => (n > 0) ? n - 1 : 0);
}
}
¿Es este uso correcto? Voy a evitar situaciones tales como:
- Tema 1: Añadir llamadas ("a"), foo [ "a"] es ahora 1.
- Tema 1 se intercambia por Tema 2.
- Tema 2: llamadas Eliminar ("a"), foo ["a"] ahora 0.
- El hilo 2 se intercambia por el hilo 1.
- Tema 1: Solicita foo ["a"] y asume que el valor es 1 pero en realidad es 0.
Buen punto. Editado para reflejar la equivalencia con la implementación del diccionario. – Bullines
¿Qué son 's_ConcurrentRequests' y' url'? También actualicé mi respuesta para señalar una inequidad con el método 'Agregar 'también. – Domenic
Interlocked.Decrement podría estar bien, pero tendría que asegurarme de que los valores sean mayores que 0. Esto podría estar bien, porque los valores nunca deberían ser menores que cero. Pero el truco será tener una forma segura de verificar que el valor sea aún mayor que cero. Quizás Interlock.Exchange? – Bullines