En cuanto a la variable local que pasa en Thread

Me está costando entender la salida inesperada para el siguiente progtwig:

class ThreadTest { static void Main() { for(int i = 0; i  Console.Write(i)).Start(); } } 

Consultas: ¿código diferente que se ejecuta en un hilo diferente tiene stacks separadas? Si es así, entonces las variables deben preservar sus valores ya que int es un tipo de valor?

Cada hilo tiene su propia stack. El problema al que te enfrentas no tiene nada que ver con la stack. El problema es la forma en que genera el código para su delegado anónimo. Use la herramienta como refectorio para comprender el código que está generando. Lo siguiente solucionará su problema:

 static void Main() { for (int i = 0; i < 10; i++) { int capture = i; new Thread(() => Console.Write(capture)).Start(); } } 

Bajo el capó

Cada vez que utiliza una variable del ámbito externo (en su caso, la variable i) en un delegado anónimo, el comstackdor genera una nueva clase que ajusta la función anónima junto con los datos que utiliza desde el ámbito externo. Entonces, en su caso, la clase generada contiene una función y un miembro de datos para capturar el valor de la variable i. La definición de clase se ve algo así como:

 class SomeClass { public int i { get; set; } public void Write() { Console.WriteLine(i); } } 

El comstackdor vuelve a escribir su código de la siguiente manera:

 SomeClass someObj = new SomeClass(); for (int i = 0; i < 10; i++) { someObj.i = i; new Thread(someObj.Write).Start(); } 

y de ahí el problema - que estás enfrentando. Cuando captura una variable, el comstackdor hace lo siguiente:

 for (int i = 0; i < 10; i++) { SomeClass someObj = new SomeClass(); someObj.i = i; new Thread(someObj.Write).Start(); } 

Tenga en cuenta la diferencia en la creación de instancias SomeClass. Cuando captura una variable, crea tantas instancias como número de iteraciones. Si no captura una variable, intenta usar la misma instancia para todas las iteraciones.

Espero, la explicación anterior aclarará tu duda.

Gracias

Sí, los hilos tienen sus propios stacks. Pero aquí también tienes un problema con la captura de variables. Intenta cambiar el código a:

 class ThreadTest { static void Main() { for(int i = 0; i < 10; i++) { int j = i; new Thread(() => Console.Write(j)).Start(); } } } 

Observe el cambio en la salida? Cada hilo se inicia con una referencia a la variable, no el valor. Cuando inserto el int j = i; línea, estamos rompiendo la captura variable. Su salida inesperada tiene menos que ver con el enhebrado que con los cierres.