Ich versuche Multithreading zu verstehen. Ich habe ein Beispiel, das zwei Threads von der Main-Methode in der Konsolen-App ausführt.
%Vor%Was passiert, ist, dass meine Konsole schwarz wird, nichts darauf geschrieben ist, aber wenn ich irgendeine Taste drücke, zeigt sie korrekte Ergebnisse an. Warum?
Einige von uns (mit Blick auf die Kommentare unter der Frage) sehen, dass die neuen Threads vollständig ausgeführt werden, bevor Console.ReadKey()
aufgerufen wird, während andere den ersten Thread vor den neuen Threads sehen und auf die Eingabe über Console.ReadKey()
warten bevor die neuen Threads ausführt.
Sie haben drei Threads, die alle ihr eigenes Ding machen, alle potentiell auf die Konsole schreiben und andere Logik ausführen, und Sie haben nicht wirklich die Kontrolle darüber, welche man zu einem bestimmten Zeitpunkt ausführt.
Von dem Eric wurde gesagt, dass dieses Verhalten erwartet wird und dass Sie die neuen Threads ausführen vorhersehbar unvorhersehbar. (hat seinen Kommentar hier gepostet, falls die Kommentare bereinigt sind)
Lesen Sie meine zwei grundlegenden Regeln noch einmal: (1) Programme, die versuchen, UI auf zwei Threads zu tun, sind gebrochen, und (2) erwarten Sie, dass sich nichts normal verhält. Ich habe keine Erwartung, dass das gebrochene Programm irgendein Verhalten hervorbringen wird. Darüber hinaus erwarte ich nicht, dass das Verhalten eines fehlerhaften Programms über mehrere Läufe oder Maschinen hinweg konsistent ist. Ich erwarte auch nicht, dass das Verhalten inkonsistent sein wird. Defekte Programme sind kaputt; Sie müssen nicht konsistent oder inkonsistent in ihrem schlechten Verhalten sein.
Es gibt einen Aufruf, mit dem Sie den ersten (Haupt-) Thread (der der aufrufende Thread ist) blockieren können, bis die neuen Threads fertig ausgeführt sind, und zwar Thread.Join . Sie haben immer noch nicht die Kontrolle darüber, welche Reihenfolge die beiden neuen Threads ausführen und in die Konsole schreiben, aber zumindest ist der erste Thread pausiert.
%Vor%Lassen Sie mich den ersten erzeugten Thread als thread1, den nächsten erzeugten Thread als thread2 nennen. Außerdem nennen wir den Thread, der thread1 und thread2 als mainthread erstellt.
Es gibt natürlich keine Garantie, dass der Code in thread1 vor thread2 oder mainthread ausgeführt wird. Je nach den Umständen kann es vorkommen, dass Console.WriteLine()
vor dem Anhalten für Console.ReadKey()
ausgeführt wird.
Warum stoppt es für Console.ReadKey()
, das du fragen magst? da die Konsolen-E / A synchronisiert ist. Eine lock
-Anweisung um die Konsole. * Aufruf könnte es offensichtlicher machen (für Demo-Code)
Wenn Sie möchten, dass die anderen zwei Threads die Verarbeitung beenden, bevor Sie Console.ReadKey()
aufrufen (blockierender E / A-Aufruf), sollten Sie thread1.Join()
und thread2.Join()
aufrufen, bevor Sie Console.ReadKey()
Tags und Links c# multithreading