So verwenden Sie Multi-Threading mit Aufgaben in C#
Verwenden der parallelen Aufgabenbibliothek in .NET 4.0
Przemyslaw Klos / EyeEm / Getty Images
Das Computerprogrammierung Der Begriff „Thread“ ist die Abkürzung für „Thread of Execution“, bei dem ein Prozessor einem bestimmten Pfad durch Ihren Code folgt. Das Konzept, mehr als einem Thread gleichzeitig zu folgen, führt in das Thema Multitasking und Multithreading ein.
Eine Anwendung enthält einen oder mehrere Prozesse. Stellen Sie sich einen Prozess als ein Programm vor, das auf Ihrem Computer ausgeführt wird. Jetzt hat jeder Prozess einen oder mehrere Threads. Eine Spielanwendung kann einen Thread zum Laden von Ressourcen von der Festplatte, einen anderen für die KI und einen weiteren zum Ausführen des Spiels als Server haben.
In .NET/Windows weist das Betriebssystem einem Thread Prozessorzeit zu. Jeder Thread verfolgt Ausnahmebehandlungsroutinen und die Priorität, mit der er ausgeführt wird, und er kann den Threadkontext irgendwo speichern, bis er ausgeführt wird. Thread-Kontext sind die Informationen, die der Thread zum Fortsetzen benötigt.
Multitasking mit Threads
Threads nehmen etwas Speicherplatz in Anspruch und ihre Erstellung dauert ein wenig, daher möchten Sie normalerweise nicht viele verwenden. Denken Sie daran, dass sie um Prozessorzeit konkurrieren. Wenn Ihr Computer über mehrere CPUs verfügt, führt Windows oder .NET möglicherweise jeden Thread auf einer anderen CPU aus. Wenn jedoch mehrere Threads auf derselben CPU ausgeführt werden, kann jeweils nur einer aktiv sein, und das Wechseln von Threads dauert einige Zeit.
Die CPU führt einen Thread für einige Millionen Anweisungen aus und wechselt dann zu einem anderen Thread. Alle CPU-Register, der aktuelle Programmausführungspunkt und der Stack müssen für den ersten Thread irgendwo gespeichert und dann für den nächsten Thread von woanders wiederhergestellt werden.
Thread erstellen
Im Namensraum System. Einfädeln , finden Sie den Gewindetyp. Der Konstruktor-Thread (ThreadStart) erstellt eine Instanz eines Threads. Allerdings in letzter Zeit C# code, ist es wahrscheinlicher, einen Lambda-Ausdruck zu übergeben, der die Methode mit beliebigen Parametern aufruft.
Wenn Sie sich nicht sicher sind Lambda-Ausdrücke , könnte es sich lohnen, LINQ auszuprobieren.
Hier ist ein Beispiel für einen Thread, der erstellt und gestartet wird:
|_+_| |_+_|
Dieses Beispiel schreibt lediglich '1' in die Konsole. Der Haupt-Thread schreibt 10 Mal eine '0' auf die Konsole, jedes Mal gefolgt von einem 'A' oder 'D', je nachdem, ob der andere Thread noch lebt oder tot ist.
Der andere Thread läuft nur einmal und schreibt eine '1'. Nach der Verzögerung von einer halben Sekunde im Write1()-Thread wird der Thread beendet und Task.IsAlive in der Hauptschleife gibt jetzt „D“ zurück.
Thread-Pool und Task-Parallelbibliothek
Anstatt Ihren eigenen Thread zu erstellen, verwenden Sie einen Thread-Pool, es sei denn, Sie müssen dies wirklich tun. Ab .NET 4.0 haben wir Zugriff auf die Task Parallel Library (TPL). Wie im vorherigen Beispiel brauchen wir wieder ein bisschen LINQ, und ja, es sind alles Lambda-Ausdrücke.
Aufgaben verwendet dieThread-Poolhinter den Kulissen, sondern nutzen Sie die Threads je nach Anzahl der verwendeten Threads besser.
Das Hauptobjekt in der TPL ist eine Aufgabe. Dies ist eine Klasse, die einen asynchronen Vorgang darstellt. Der gebräuchlichste Weg, Dinge zum Laufen zu bringen, ist mit Task.Factory.StartNew wie in:
|_+_|Wobei DoSomething() die Methode ist, die ausgeführt wird. Es ist möglich, eine Aufgabe zu erstellen und sie nicht sofort auszuführen. Verwenden Sie in diesem Fall einfach Task wie folgt:
|_+_|
Das startet den Thread erst, wenn .Start() aufgerufen wird. Im folgenden Beispiel sind fünf Aufgaben.
|_+_|Führen Sie das aus, und Sie erhalten die Ausgabe der Ziffern 0 bis 4 in einer zufälligen Reihenfolge, z. B. 03214. Das liegt daran, dass die Reihenfolge der Aufgabenausführung von .NET bestimmt wird.
Sie fragen sich vielleicht, warum var value = i benötigt wird. Versuchen Sie, es zu entfernen und Write(i) aufzurufen, und Sie werden etwas Unerwartetes wie 55555 sehen. Warum ist das so? Dies liegt daran, dass die Aufgabe den Wert von i zum Zeitpunkt der Ausführung der Aufgabe anzeigt, nicht zum Zeitpunkt der Erstellung der Aufgabe. Durch die Erstellung eines neuen Variable jedes Mal in der Schleife wird jeder der fünf Werte korrekt gespeichert und abgeholt.