habe ein Problem, hoffe, dass mir jemand helfen kann.
Ich versuche 4 Task in einer Schleife zu starten, bekomme aber eine ArgumentOutOfRangeException:
%Vor%Die Schleife erhält einen Überlauf, weil i = 4
istWenn ich die Tasks ohne Schleife starte, laufen sie ohne Probleme:
%Vor%weiß nicht warum? Die Tasks GetData von einer Siemens SPS über Socket Connection. Die SPS unterstützt bis zu 32 Verbindungen. Ich erhalte 200 Bytes pro Verbindung.
%Vor%irgendeine Idee?
Grüße Sam
Es wird wahrscheinlich durch eine Schließungsproblem .
Versuchen Sie Folgendes:
%Vor% Was wahrscheinlich passiert, ist, dass wenn der letzte Thread gestartet wird, die Schleife i
bereits auf 4 erhöht hat, und das ist der Wert, der an GetData()
übergeben wird. Den Wert von i
in eine separate Variable index
einzufangen und stattdessen zu verwenden, sollte das Problem lösen.
Als Beispiel, wenn Sie diesen Code versuchen:
%Vor%es wird Ihnen oft diese Art von Ausgabe geben:
%Vor%Ändern Sie diesen Code in:
%Vor%und Sie erhalten etwas wie
%Vor%Beachten Sie, wie es NOCH NICHT NOTWENDIG IST! Sie sehen alle korrekten Werte ausgedruckt, aber in einer unbestimmten Reihenfolge. Multithreading ist tricky!
In C # 5 befindet sich die Schleifenvariable einer foreach logisch innerhalb der Schleife und daher schließen sich Closures bei jeder neuen Kopie der Variablen . Die "for" -Schleife wird nicht geändert.
Ein anderer Weg ist der:
Der Demo-Code wie folgt:
%Vor%AUSGABE:
%Vor% Hinweis: Es ist new Task<byte[]>(GetData,i);
nicht new Task<byte[]>(()=>GetData(i));
() = & gt; v bedeutet "gebe den aktuellen Wert der Variablen v zurück", nicht "gebe den Wert zurück v war zurück, als der Delegat erstellt wurde". Verschlüsse schließen sich über Variablen, nicht über Werte .
Die new Task<byte[]>(GetData,i);
haben also kein Closures Problem