/ / Inkonsistente Variablenwerte in C # Multithreading [Duplizieren] - c #, Multithreading

inkonsistente Variablenwerte in C # Multithreading [Duplizieren] - c #, Multithreading

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 № 1

Ich 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.