[ThreadStatic]
se define usando atributo mientras que ThreadLocal<T>
usa genérico. ¿Por qué se eligieron diferentes soluciones de diseño? ¿Cuáles son las ventajas y desventajas de utilizar atributos genéricos en lugar de en este caso?
[ThreadStatic]
se define usando atributo mientras que ThreadLocal<T>
usa genérico. ¿Por qué se eligieron diferentes soluciones de diseño? ¿Cuáles son las ventajas y desventajas de utilizar atributos genéricos en lugar de en este caso?
Respuestas:
Algo que la publicación del blog anotó en los comentarios no hace explícito, pero me parece muy importante, es que [ThreadStatic]
no inicializa automáticamente las cosas para cada hilo. Por ejemplo, digamos que tiene esto:
[ThreadStatic]
private static int Foo = 42;
El primer hilo que usa esto se verá Foo
inicializado en 42
. Pero los hilos posteriores no lo harán. El inicializador funciona solo para el primer hilo. Entonces terminas teniendo que escribir código para verificar si está inicializado.
ThreadLocal<T>
resuelve ese problema permitiéndole proporcionar 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 en usar en [ThreadStatic]
lugar de ThreadLocal<T>
.
ThreadLocal<T>
esté disponible en .NET 4 y versiones posteriores, y el ThreadStatic
atributo también está disponible en 3.5 y versiones posteriores.
ThreadLocal<T>
implementa IDisposable
y generalmente lo obliga a implementar IDisposable
también, lo que obliga a las personas que llaman a deshacerse de usted y, por lo tanto, implementarlo IDisposable
también ...
ThreadLocal
o ThreadStatic
con subprocesos de grupo. Esos valores permanecerán durante toda la vida útil del subproceso del grupo, no solo para la tarea que le asigne. Eso puede causarle problemas de formas bastante no obvias. Consulte stackoverflow.com/questions/561518/… y preguntas similares para obtener más información.
static
? Ver msdn.microsoft.com/en-us/library/…
ThreadStatic Initialize solo en el primer subproceso, ThreadLocal Initialize para cada subproceso. A continuación se muestra 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();
}
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 de value
para cada hilo, incluido el hilo principal.
Por lo tanto, una variable ThreadStatic se inicializará a su valor predeterminado en otros subprocesos, excepto en el subproceso en el que se creó.
Si queremos inicializar la variable en cada hilo a nuestra manera, use ThreadLocal.