In .NET gibt es zwei Klassen: Task
y Thread
.
- Worin besteht der Unterschied zwischen diesen Klassen?
- Wann ist es besser, die
Thread
überTask
(und vice versa)?
In .NET gibt es zwei Klassen: Task
y Thread
.
Thread
über Task
(und vice versa)?Thread
ist ein Konzept auf niedrigerer Ebene: Wenn Sie direkt einen Thread starten, müssen Sie wissen Es wird ein separater Thread sein, der nicht im Thread-Pool ausgeführt wird usw.
Task
ist jedoch mehr als nur eine Abstraktion von "wo ein Code ausgeführt werden soll" - es ist wirklich nur "das Versprechen eines Ergebnisses in der Zukunft". Um nur einige Beispiele zu nennen:
Task.Delay
benötigt keine tatsächliche CPU-Zeit; es ist wie das Einstellen eines Timers, der in der Zukunft abläuftWebClient.DownloadStringTaskAsync
wird lokal nicht viel CPU-Zeit beanspruchen; es stellt ein Ergebnis dar, das wahrscheinlich die meiste Zeit mit Netzwerklatenz oder Remote-Arbeit (auf dem Webserver) verbringen wirdTask.Run()
wirklich es Sie sagen: "Ich möchte, dass Sie diesen Code separat ausführen"; der genaue Thread, in dem dieser Code ausgeführt wird, hängt von einer Reihe von Faktoren ab.Beachten Sie, dass die Task<T>
Abstraktion ist für die asynchrone Unterstützung in C# 5 von zentraler Bedeutung.
Im Allgemeinen würde ich empfehlen, dass Sie die Abstraktion auf höherer Ebene verwenden, wo immer Sie können: In modernem C#-Code sollten Sie selten explizit Ihren eigenen Thread starten müssen.
Normalerweise hört man Aufgabe ist ein Konzept höherer Ebene als Thread ... und das ist es, was dieser Satz bedeutet:
Sie können Abort/ThreadAbortedException nicht verwenden, Sie sollten cancel event in Ihrem "Business Code" regelmäßig testen token.IsCancellationRequested
Flag (vermeiden Sie auch lange oder zeitlose Verbindungen z.B. zu db, sonst werden Sie nie die Chance haben, dieses Flag zu testen). Aus dem gleichen Grund Thread.Sleep(delay)
Aufruf sollte ersetzt werden durch Task.Delay(delay, token)
Aufruf (Übergabe des Tokens, um die Verzögerung unterbrechen zu können).
Es gibt keine Threads Suspend
y Resume
Methodenfunktionalität mit Aufgaben. Instanz einer Aufgabe kann nicht wiederverwendet werden entweder.
Aber Sie erhalten zwei neue Werkzeuge:
a) Fortsetzungen
// continuation with ContinueWhenAll - execute the delegate, when ALL
// tasks[] had been finished; other option is ContinueWhenAny
Task.Factory.ContinueWhenAll(
tasks,
() => {
int answer = tasks[0].Result + tasks[1].Result;
Console.WriteLine("The answer is {0}", answer);
}
);
b) verschachtelte/untergeordnete Aufgaben
//StartNew - starts task immediately, parent ends whith child
var parent = Task.Factory.StartNew
(() => {
var child = Task.Factory.StartNew(() =>
{
//...
});
},
TaskCreationOptions.AttachedToParent
);
Der System-Thread ist also vollständig vor der Aufgabe verborgen, aber der Code der Aufgabe wird dennoch im konkreten System-Thread ausgeführt. System-Threads sind Ressourcen für Aufgaben und natürlich gibt es noch einen Thread-Pool unter der Haube der parallelen Ausführung von Aufgaben. Es kann verschiedene Strategien geben, wie Threads neue Aufgaben zur Ausführung erhalten. Eine weitere gemeinsam genutzte Ressource TaskScheduler kümmert sich darum. Einige Probleme, die TaskScheduler löst 1) bevorzugt die Ausführung einer Aufgabe und ihrer Verknüpfung im selben Thread, um die Umschaltkosten zu minimieren - auch bekannt als Inline-Ausführung ) 2) lieber Aufgaben in der Reihenfolge ausführen, in der sie gestartet wurden - aka PreferFairness 3) effektivere Verteilung von Aufgaben zwischen inaktiven Threads je nach "Vorkenntnis der Aufgabenaktivität" - auch bekannt als Arbeit stehlen . Wichtig: im Allgemeinen ist "async" nicht dasselbe wie "parallel". Mit den TaskScheduler-Optionen können Sie asynchrone Aufgaben so einstellen, dass sie in einem Thread synchron ausgeführt werden. Um parallele Codeausführung auszudrücken, können höhere Abstraktionen (als Tasks) verwendet werden: Parallel.ForEach
, PLINQ
, Dataflow
.
Tasks sind mit C# async/await-Funktionen integriert, auch bekannt als Versprechen Modell , z.B. dort requestButton.Clicked += async (o, e) => ProcessResponce(await client.RequestAsync(e.ResourceName));
die Ausführung von client.RequestAsync
wird den UI-Thread nicht blockieren. Wichtig: unter der Haube Clicked
Der Aufruf von Delegaten ist absolut regulär (das gesamte Threading wird vom Compiler durchgeführt).
Das reicht aus, um eine Entscheidung zu treffen. Wenn Sie die Cancel-Funktionalität des Aufrufs von Legacy-APIs unterstützen müssen, die zum Hängen neigen (z.B. zeitlose Verbindung) und für diesen Fall Thread.Abort() unterstützen, oder wenn Sie Multithread-Hintergrundberechnungen erstellen und den Wechsel zwischen Threads mit Suspend/Resume optimieren wollen, d.h. die parallele Ausführung manuell verwalten wollen - bleiben Sie bei Thread. Andernfalls sollten Sie sich für Tasks entscheiden, da diese eine einfache Manipulation von Gruppen ermöglichen, in die Sprache integriert sind und Entwickler produktiver machen. Aufgabenparallele Bibliothek (TPL) .
En Thread
Klasse dient der Erstellung und Bearbeitung einer fil in Windows.
A Task
stellt eine asynchrone Operation dar und ist Teil der Aufgabe Parallele Bibliothek , eine Reihe von APIs für die asynchrone und parallele Ausführung von Aufgaben.
In den alten Tagen (d.h. vor TPL) war es üblich, dass die Verwendung des Thread
Klasse war eine der Standardmethoden, um Code im Hintergrund oder parallel auszuführen (eine bessere Alternative war oft die Verwendung einer ThreadPool
), dies war jedoch umständlich und hatte mehrere Nachteile, nicht zuletzt den Leistungs-Overhead, der durch die Erstellung eines völlig neuen Threads zur Ausführung einer Aufgabe im Hintergrund entsteht.
Heutzutage ist die Verwendung von Tasks und der TPL in 90 % der Fälle eine weitaus bessere Lösung, da sie Abstraktionen bietet, die eine weitaus effizientere Nutzung der Systemressourcen ermöglichen. Ich kann mir vorstellen, dass es ein paar Szenarien gibt, in denen man explizit die Kontrolle über den Thread haben möchte, auf dem man seinen Code ausführt, aber im Allgemeinen, wenn man etwas asynchron ausführen möchte, sollte die erste Anlaufstelle die TPL sein.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.