Wenn ich Threads verwende, um Dinge auf die Konsole zu drucken, warum erzeugt es dann seltsame Ergebnisse?

8

Ich bin in letzter Zeit auf Threads gestoßen, als ich das sehr schöne PDF von Rob Miles ( hier ) gelesen habe. Er hatte ein Beispiel auf Seite 160 (2012, C # pdf), aber es hat nicht nur leere Schleifen auf der Konsole geschrieben.

Ich habe einen sehr einfachen Thread geschrieben, der eine Schleife erzeugt, die 10 Threads erstellt, die ihre IDs für jedes Vielfache von 1000 auf den Bildschirm schreiben. Das war nett - es zeigte mir, wie Threads zusammen liefen. Meine Fragen beginnen mit dem Warum ist meine Ausgabe so verwirrt? Wenn ich das Programm unten ausführe, bekomme ich oft mehrere "Thread 3 Finished" -Zeilen, bei denen ich ziemlich sicher bin, dass ich nur eine davon haben sollte.

Ich habe eine "Sperre" von MSDN hinzugefügt die Schleife, aber es scheint immer noch eine ungerade Ausgabe zu erzeugen (ich werde ein Beispiel unten setzen).

%Vor%

Ich dachte, es geht mir gut - ich habe lokale Variablen (meine Zählschleife), ich habe ein int, das vermutlich nicht per Referenz übergeben wird, und später habe ich versucht, es zu sperren, während ich es mache. Keine Freude. Was müsste ich tun, damit die Ausgabe vernünftig aussieht? Ich habe versucht, Deubg.Print zu beheben, aber es hat auch Fehler (unten).

Schließlich möchte ich Threading in einer größeren Anwendung verwenden, aber wenn ich es hier nicht richtig verstehe, bin ich mir nicht sicher, ob ich das möchte!

Beispiel Ausgabe von der debug.print-Zeile am Ende: (beachten Sie die Vielfachen) ...

%Vor%

Lassen Sie es mich wissen, wenn ich weitere Informationen über das, was ich versucht habe, anbieten kann.

    
Sisyphus 13.05.2013, 10:33
quelle

2 Antworten

10

Ihr Problem hier ist, dass Sie eine "modifizierte Schließung" für die Variable loop verwenden.

Obwohl dies für foreach -Schleifen behoben wurde, haben for -Schleifen immer noch das Problem (und werden es immer tun)

Um es zu beheben, ändern Sie Ihre Main () zu diesem:

%Vor%

Siehe hier für weitere Details:

Zugriff auf Modified Closure

Eric Lipperts Artikel auf Closures

    
Matthew Watson 13.05.2013, 10:39
quelle
5

Verwenden Sie Parallel.For , anstatt Threads selbst in einer Schleife zu starten:

%Vor%

Wenn Sie ein zusätzliches Argument (zB w ) als Teil davon übergeben müssen, können Sie dies tun:

%Vor%

Die andere Sache, die es zu beachten gilt, ist, dass das Objekt Console exklusiv ist. Wenn Sie es aus einem Thread verwenden, werden alle anderen Threads blockiert, die versuchen, es zu verwenden, bis es fertig ist.

Auch Ihr lock (sync) wird verhindern, dass zwei Threads gleichzeitig ihre Operation ausführen.

Bedenken Sie, dass Ihre Threads nicht in einer bestimmten Reihenfolge ausgeführt werden.

    
PhonicUK 13.05.2013 10:38
quelle