Si tiene una variable compartida (por ejemplo, como un campo estático de una clase, o como un campo de un objeto compartido), y ese campo u objeto se va a utilizar de forma cruzada, entonces, sí, usted debe asegurarse de que el acceso a esa variable esté protegido mediante una operación atómica. El procesador x86 tiene intrínsecos para asegurarse de que esto ocurra, y esta instalación se expone a través de los métodos de clase System.Threading.Interlocked.
Por ejemplo:
class Program
{
public static Int64 UnsafeSharedData;
public static Int64 SafeSharedData;
static void Main(string[] args)
{
Action<Int32> unsafeAdd = i => { UnsafeSharedData += i; };
Action<Int32> unsafeSubtract = i => { UnsafeSharedData -= i; };
Action<Int32> safeAdd = i => Interlocked.Add(ref SafeSharedData, i);
Action<Int32> safeSubtract = i => Interlocked.Add(ref SafeSharedData, -i);
WaitHandle[] waitHandles = new[] { new ManualResetEvent(false),
new ManualResetEvent(false),
new ManualResetEvent(false),
new ManualResetEvent(false)};
Action<Action<Int32>, Object> compute = (a, e) =>
{
for (Int32 i = 1; i <= 1000000; i++)
{
a(i);
Thread.Sleep(0);
}
((ManualResetEvent) e).Set();
};
ThreadPool.QueueUserWorkItem(o => compute(unsafeAdd, o), waitHandles[0]);
ThreadPool.QueueUserWorkItem(o => compute(unsafeSubtract, o), waitHandles[1]);
ThreadPool.QueueUserWorkItem(o => compute(safeAdd, o), waitHandles[2]);
ThreadPool.QueueUserWorkItem(o => compute(safeSubtract, o), waitHandles[3]);
WaitHandle.WaitAll(waitHandles);
Debug.WriteLine("Unsafe: " + UnsafeSharedData);
Debug.WriteLine("Safe: " + SafeSharedData);
}
}
Los resultados:
inseguro: -24,050,275,641 Segura: 0
En una nota interesante, me encontré con este en modo x64 en Vista 64. Esto muestra que los campos de 64 bits son tratados como campos de 32 bits por el tiempo de ejecución, es decir, las operaciones de 64 bits no son atómicas. Alguien sabe si esto es un problema CLR o un problema x64?
Para operaciones atómicas en Int64, puede usar la clase InterLocked (http://msdn.microsoft.com/en-us/library/system.threading.interlocked.add.aspx). –