c# generics attributes thread-local threadstatic

c# - ThreadStatic vs ThreadLocal<T>: ¿es genérico mejor que el atributo?



generics attributes (3)

[ThreadStatic] se define usando el atributo mientras ThreadLocal<T> usa genérico. ¿Por qué se eligieron diferentes soluciones de diseño? ¿Cuáles son las ventajas y desventajas del uso de atributos genéricos en este caso?


Algo que la publicación del blog notó en los comentarios no lo hace explícito, pero me parece que es muy importante, es que [ThreadStatic] no inicializa automáticamente las cosas para cada tema. Por ejemplo, di que tienes esto:

[ThreadStatic] private static int Foo = 42;

El primer hilo que use esto verá Foo inicializado a 42 . Pero los hilos subsecuentes no lo harán. El inicializador funciona solo para el primer subproceso. Entonces terminas escribiendo código para verificar si está inicializado.

ThreadLocal<T> resuelve ese problema permitiéndole suministrar una función de inicialización (como muestra el blog de Reed) que se ejecuta antes de la primera vez que se accede al elemento.

En mi opinión, no hay ninguna ventaja al usar [ThreadStatic] lugar de ThreadLocal<T> .


La idea principal detrás de ThreadStatic es mantener una copia separada de la variable para cada hilo .

class Program { [ThreadStatic] static int value = 10; static void Main(string[] args) { value = 25; Task t1 = Task.Run(() => { value++; Console.WriteLine("T1: " + value); }); Task t2 = Task.Run(() => { value++; Console.WriteLine("T2: " + value); }); Task t3 = Task.Run(() => { value++; Console.WriteLine("T3: " + value); }); Console.WriteLine("Main Thread : " + value); Task.WaitAll(t1, t2, t3); Console.ReadKey(); } }

En el fragmento anterior, tenemos una copia separada del value de cada hilo, incluido el hilo principal.

Por lo tanto, una variable ThreadStatic se inicializará a su valor predeterminado en otros hilos, excepto en el hilo en el que se creó.

Si queremos inicializar la variable en cada hilo de nuestra propia manera, use ThreadLocal.


ThreadStatic Initialize solo en el primer hilo, ThreadLocal Initialize para cada hilo. Debajo está la demostración simple:

public static ThreadLocal<int> _threadlocal = new ThreadLocal<int>(() => { return Thread.CurrentThread.ManagedThreadId; }); public static void Main() { new Thread(() => { for (int x = 0; x < _threadlocal.Value; x++) { Console.WriteLine("First Thread: {0}", x); } }).Start(); new Thread(() => { for (int x = 0; x < _threadlocal.Value; x++) { Console.WriteLine("Second Thread: {0}", x); } }).Start(); Console.ReadKey(); }