Usted dice que no quiere usar lock
por razones de rendimiento, pero ¿lo ha probado? Un bloqueo no disputado (que es probable que sea así, por los sonidos del mismo) es bastante barato.
Generalmente prefiero "obviamente correcto" en lugar de "inteligente y posiblemente mejor rendimiento" cuando se trata de enhebrar (y en general, pero especialmente para enhebrar).
Comparativa de su aplicación con y sin bloqueo, y vea si puede notar la diferencia. Si el bloqueo hace una diferencia significativa de , entonces seguro, use astucia. De lo contrario, me quedaría con un candado.
Una cosa que puede querer hacer es usar Interlocked.Increment
con un int
y simplemente echarlo cuando sea necesario para obtener una uint
, así:
using System;
using System.Reflection;
using System.Threading;
public class Test
{
private static int count = int.MaxValue-1;
public static uint IncrementCount()
{
int newValue = Interlocked.Increment(ref count);
return (uint) newValue;
}
public static void Main()
{
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
Console.WriteLine(IncrementCount());
}
}
Salida:
2147483647
2147483648
2147483649
(En otras palabras, se envuelve sin problemas.)
Eso solo asegura que cualquier cambio en el v ariable se escriben en la memoria de inmediato, en lugar de esperar hasta que el hilo ceda o el valor se desplace en un registro. No protege el acceso al campo, es decir, dos (o más) subprocesos pueden leer el mismo valor, incrementar una vez y escribir de nuevo, aumentando efectivamente el valor en 1. –
Lea los requisitos anteriores y también el ejemplo en http: //msdn.microsoft.com/en-us/library/7a2f3ay4.aspx. Para el caso dado, es suficiente. – Sesh
¿Qué tan eficiente es la volatilidad en comparación con Interlocked.Increment? ¿Mismo? ¿Mejor? – jrista