Por favor, compruebe el código de ejemplo a continuación:comportamiento inesperado para ThreadPool.QueueUserWorkItem
public class Sample
{
public int counter { get; set; }
public string ID;
public void RunCount()
{
for (int i = 0; i < counter; i++)
{
Thread.Sleep(1000);
Console.WriteLine(this.ID + " : " + i.ToString());
}
}
}
class Test
{
static void Main()
{
Sample[] arrSample = new Sample[4];
for (int i = 0; i < arrSample.Length; i++)
{
arrSample[i] = new Sample();
arrSample[i].ID = "Sample-" + i.ToString();
arrSample[i].counter = 10;
}
foreach (Sample s in arrSample)
{
ThreadPool.QueueUserWorkItem(callback => s.RunCount());
}
Console.ReadKey();
}
}
La salida esperada para esta muestra debe ser algo como:
Sample-0 : 0
Sample-1 : 0
Sample-2 : 0
Sample-3 : 0
Sample-0 : 1
Sample-1 : 1
Sample-2 : 1
Sample-3 : 1
.
.
.
Sin embargo, cuando se ejecuta este código, mostraría algo como esto en su lugar:
Sample-3 : 0
Sample-3 : 0
Sample-3 : 0
Sample-3 : 1
Sample-3 : 1
Sample-3 : 0
Sample-3 : 2
Sample-3 : 2
Sample-3 : 1
Sample-3 : 1
.
.
.
Puedo entender que el orden en el que el trío Los anuncios que se ejecutan pueden diferir y, por lo tanto, el recuento no aumenta en la modalidad de round robin. Sin embargo, no entiendo por qué todos los ID
s se muestran como Sample-3
, mientras que la ejecución está sucediendo claramente independientemente uno del otro.
¿Se están utilizando diferentes objetos con diferentes subprocesos?
Otro día, otra persona sin saber cómo utilizar adecuadamente los cierres. No es de extrañar que Java sea tan reacia a agregarlos ... – leppie
Lo que leppie está diciendo es que captura la variable 's' en lugar de su valor. Para cuando los hilos se ejecutan, la iteración termina y 's' queda con su último valor. – Zarat
Creo que estoy perdido aquí .. ¿Qué es el problema de cierre BTW –