Une question similaire a été posée here, mais les réponses semblent généralement toutes se rapporter à la notation lambda. Je reçois un résultat similaire sans le lambda, donc je pensais que je vais demander des éclaircissements:Conditions de course pour le démarrage du thread
Dire que j'ai quelque chose comme ceci:
for (int i = 0; i < 5; i++)
(new Thread(new ThreadStart(delegate()
{
Console.WriteLine("Thread " + i);
}))).Start();
On pourrait attendre la sortie suivante:
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
Maintenant, je me rends compte que les threads ne sont pas démarrés dans un ordre particulier, alors supposons que les lignes ci-dessus peuvent sortir dans n'importe quel ordre.
Mais ce n'est pas ce qui se passe. Qu'arrive-t- place:
Thread 3
Thread 4
Thread 4
Thread 4
Thread 4
ou quelque chose de similaire, ce qui me porte à croire que, plutôt que de passer la valeur si i, il passe la référence. (Ce qui est bizarre, car un int est un type de valeur).
Faire quelque chose comme ceci:
for (int i = 0; i < 5; i++)
(new Thread(new ThreadStart(delegate()
{
int j = i;
Console.WriteLine("Thread " + j);
}))).Start();
ne vous aide pas non plus, même si nous avons fait une copie de i. Je suppose que la raison en est qu'il n'a pas fait une copie de moi à temps.
Faire quelque chose comme ceci:
for (int i = 0; i < 5; i++)
{
(new Thread(new ThreadStart(delegate()
{
Console.WriteLine("Thread " + i);
}))).Start();
Thread.Sleep(50);
}
semble résoudre le problème, mais il est extrêmement indésirable que nous gaspillons 50ms à chaque itération, pour ne pas mentionner le fait que si l'ordinateur est lourdement chargé alors peut-être que 50ms ne suffiront peut-être pas.
Voici un exemple avec mon problème actuel, spécifique:
Thread t = new Thread(new ThreadStart(delgate()
{
threadLogic(param1, param2, param3, param4);
}));
t.Start();
param1 = param2 = param3 = param4 = null;
avec:
void threadLogic(object param1, object param2, object param3, object param4)
{
// Do some stuff here...
}
Je veux threadLogic() pour exécuter dans son propre thread, mais le code ci-dessus donne une valeur nulle exception de référence. Je suppose que c'est parce que les valeurs sont définies sur null avant que le thread a eu une chance de démarrer.
Encore une fois, mettre un Thread.Sleep (100) fonctionne, mais c'est une solution terrible de tous les aspects. Qu'est-ce que vous recommandez pour ce type particulier de condition de course?
Affichez http://stackoverflow.com/questions/1930133/c-closures-why-is-the-loopvariable-captured-by-reference et http://stackoverflow.com/ questions/1923577/different-behavior-when-starting-a-thread-paramétréthreadstart-vs-anonymous/ – nos