Verwenden von Multithreading mit Aufgaben in C #

Der Computerprogrammierbegriff "Thread" ist eine Abkürzung für "Thread of Execution", bei der ein Prozessor einem bestimmten Pfad durch Ihren Code folgt. Das Konzept, mehrere Threads gleichzeitig zu verfolgen, 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 Spieleanwendung verfügt möglicherweise über einen Thread zum Laden von Ressourcen von der Festplatte, einen anderen zum Ausführen von KI und einen anderen zum Ausführen des Spiels als Server.

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 hat irgendwo den Thread-Kontext zu speichern, bis er ausgeführt wird. Der Thread-Kontext ist die Information, die der Thread benötigt, um fortzufahren.

Multitasking mit Threads

Threads beanspruchen ein wenig Speicherplatz und das Erstellen nimmt ein wenig Zeit in Anspruch. Daher möchten Sie in der Regel nicht viele verwenden. Denken Sie daran, sie konkurrieren um die Prozessorzeit. 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 Stapel müssen irgendwo für den ersten Thread gespeichert und dann für den nächsten Thread von woanders wiederhergestellt werden.

Einen Thread erstellen

Im Namespace System. Beim Einfädeln finden Sie den Gewindetyp. Der Konstruktorthread (ThreadStart) erstellt eine Instanz eines Threads. In neuerem C # -Code ist es jedoch wahrscheinlicher, dass ein Lambda-Ausdruck übergeben wird, der die Methode mit beliebigen Parametern aufruft.

Wenn Sie sich bei Lambda-Ausdrücken nicht sicher sind, sollten Sie LINQ ausprobieren.

Hier ist ein Beispiel für einen Thread, der erstellt und gestartet wird:

using System;
using System.Threading;
Namespace ex1

Klasse Programm

public static void Write1 ()

Console.Write ('1');
Thread.Sleep (500);

static void Main (string [] args)

var task = neuer Thread (Write1);
task.Start ();
für (var i = 0; i < 10; i++)

Console.Write ('0');
Console.Write (task.IsAlive? 'A': 'D');
Thread.Sleep (150);

Console.ReadKey ();


In diesem Beispiel wird lediglich "1" in die Konsole geschrieben. Der Haupt-Thread schreibt zehnmal eine "0" auf die Konsole, gefolgt von einem "A" oder "D", je nachdem, ob der andere Thread noch aktiv oder tot ist.

Der andere Thread läuft nur einmal und schreibt eine "1". Nach einer halben Sekunde Verzögerung im Write1 () -Thread wird der Thread beendet und die Task.IsAlive in der Hauptschleife gibt jetzt "D" zurück.

Thread-Pool und Task-Parallelbibliothek

Verwenden Sie einen Thread-Pool, anstatt einen eigenen Thread zu erstellen, 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.

Tasks verwendet den Thread-Pool im Hintergrund, nutzt die Threads jedoch je nach Anzahl der verwendeten Threads besser.

Das Hauptobjekt in der TPL ist eine Aufgabe. Dies ist eine Klasse, die eine asynchrone Operation darstellt. Die gängigste Methode, um Dinge in Gang zu setzen, ist Task.Factory.StartNew wie folgt: