Questo è più facile da capire se si guarda a ciò che accade, in termini di portata:
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(() => new PhoneJobTest(i);
t.Start();
}
traduce sostanza a qualcosa di molto vicino a questo:
int i = 0;
while (i < 10)
{
Thread t = new Thread(() => new PhoneJobTest(i);
t.Start();
i++;
}
Quando si utilizza un'espressione lambda , e usa una variabile dichiarata al di fuori della lambda (nel tuo caso, i
), il compilatore crea qualcosa chiamato chiusura: una classe temporanea che "avvolge" la variabile i e la fornisce al delegato generato dal lambda.
La chiusura è costruito allo stesso livello come variabile (i), così nel tuo caso:
int i = 0;
ClosureClass = new ClosureClass(ref i); // Defined here! (of course, not called this)
while (i < 10)
{
Thread t = new Thread(() => new PhoneJobTest(i);
t.Start();
i++;
}
A causa di questo, ogni thread ha l'stessa chiusura definito.
Quando si rielaborare il ciclo di utilizzare una temporanea, la chiusura viene generato a quel livello, invece:
for (int i = 0; i < 10; i++)
{
int jobNum = i;
ClosureClass = new ClosureClass(ref jobNum); // Defined here!
Thread t = new Thread(() => new PhoneJobTest(jobNum);
t.Start();
}
Ora, ogni thread ottiene una propria istanza, e tutto funziona correttamente.
fonte
2009-12-18 19:19:31
http://stackoverflow.com/questions/1095707/what-is-the-exact-definition-of-a-closure/ 1095770 # 1095770 –
Penso che manchi una parentesi di coppia. –
Ecco perché amo la sintassi lambda C++ 11 ... –