Ich versuche zu lernen, Multithreading in C # zu verwenden. Ich arbeite von dieses TutorialDies erklärt die Verwendung von Lambda-Ausdrücken zum Übergeben von Argumenten. Ich habe ein Spielzeugprogramm gebaut, um das zu testen, bin aber von der Ausgabe verwirrt.
Hier ist mein Code:
using System;
using System.Threading;
namespace MultithreadingApplication
{
class ThreadCreationProgram
{
public static void CallToChildThread(int id)
{
Console.WriteLine(string.Format("Child thread {0} starts", id));
}
static void Main(string[] args)
{
for (int i=0; i<10; i++)
{
Console.WriteLine(string.Format("i: {0}", i));
Thread childThread = new Thread( () => CallToChildThread (i) );
childThread.Start();
}
}
}
}
Und hier ist die Ausgabe:
i: 0
i: 1
Child thread 1 starts
i: 2
Child thread 2 starts
i: 3
Child thread 3 starts
i: 4
Child thread 4 starts
Child thread 5 starts
i: 5
i: 6
Child thread 6 starts
i: 7
i: 8
Child thread 7 starts
i: 9
Child thread 9 starts
Child thread 8 starts
Child thread 10 starts
Die Child-Funktion gibt nur den Wert der übergebenen ID aus. Ich habe erwartet, dass diese von 0 bis 9 reichen, aber CallToChildThread
zeigt stattdessen 1 bis 10. Kann jemand bitte erklären warum?
Antworten:
2 für die Antwort № 1Ich habe das Programm einfach ausgeführt und folgendes Ergebnis erhalten:
i: 0
i: 1
i: 2
Child thread 2 starts
i: 3
Child thread 2 starts
Child thread 3 starts
i: 4
Child thread 4 starts
Child thread 4 starts
i: 5
i: 6
i: 7
Child thread 7 starts
Child thread 7 starts
i: 8
i: 9
Child thread 9 starts
Child thread 9 starts
Child thread 10 starts
Dies demonstriert eines der Probleme von Multithreading: Gemeinsame Variablen. In dieser Zeile:
Thread childThread = new Thread( () => CallToChildThread (i) );
du würdest annehmen dass Sie ein Lambda mit dem erstellen Strom Wert von i
. Sie nicht. Sie erstellen ein Lambda mit einem Referenz zu i
, die Schleifenvariable. Nur wenn Ihr untergeordneter Thread den Anfang von erreicht CallToChildThread
(was zu einem späteren Zeitpunkt passieren könnte), der Wert von i
wird ausgewertet und in die lokale Variable kopiert id
.
Die Lösung ist einfach:
int _i = i;
Thread childThread = new Thread(() => CallToChildThread(_i));
Dies ergibt untergeordnete Threads von 0 bis 9.