it-swarm.com.de

Was ist der Unterschied zwischen Aufgabe und Thread?

In C # 4.0 haben wir Task im Namespace System.Threading.Tasks. Was ist der wahre Unterschied zwischen Thread und Task? Ich habe ein Beispielprogramm (Hilfe von MSDN) erstellt, um selbst damit zu lernen

Parallel.Invoke 
Parallel.For 
Parallel.ForEach 

habe aber viele zweifel da die idee nicht so klar ist.

Ich habe anfänglich in Stackoverflow nach einer ähnlichen Art von Frage gesucht, aber möglicherweise konnte ich mit diesem Fragentitel nicht dieselbe bekommen. Wenn jemand von der gleichen Art von Frage weiß, die hier früher gestellt wurde, geben Sie bitte den Verweis auf den Link an.

355
user372724

Eine Aufgabe ist etwas, das Sie erledigen möchten.

Ein Thread ist einer der vielen möglichen Arbeiter, die diese Aufgabe ausführen.

In .NET 4.0 steht ein Task für eine asynchrone Operation. Thread (s) werden verwendet, um diesen Vorgang abzuschließen, indem die Arbeit in Blöcke aufgeteilt und separaten Threads zugewiesen wird.

295
Mitch Wheat

In der Informatik ist ein Task ein zukünftiges oder ein Versprechen . (Einige Leute verwenden diese beiden Begriffe synonym, andere verwenden sie unterschiedlich. Niemand kann sich auf eine genaue Definition einigen.) Grundsätzlich ist ein Task<T> "verspricht", dir ein T zurückzugeben, aber momentan nicht, Schatz, ich bin ein bisschen beschäftigt, warum kommst du nicht später zurück?

Ein Thread ist eine Möglichkeit, dieses Versprechen zu erfüllen. Aber nicht jeder Task braucht einen brandneuen Thread. (Tatsächlich ist das Erstellen eines Threads oftmals unerwünscht, da dies sehr viel teurer ist als die erneute Verwendung eines vorhandenen Threads aus dem Threadpool. Weitere Informationen hierzu finden Sie in Kürze.) Wenn der Wert, auf den Sie warten, aus dem Dateisystem stammt oder a Datenbank oder Netzwerk, dann muss kein Thread herumstehen und auf die Daten warten, wenn er andere Anforderungen bedienen kann. Stattdessen registriert Task möglicherweise einen Rückruf, um die Werte zu erhalten, wenn sie bereit sind.

Insbesondere sagt Task nicht , warum es so lange dauert, das zurückzugeben Wert. Es kann sein, dass die Berechnung lange dauert, oder dass das Abrufen lange dauert. Nur im ersteren Fall würden Sie ein Thread verwenden, um ein Task auszuführen. (In .NET sind Threads verdammt teuer, daher möchten Sie sie im Allgemeinen so weit wie möglich vermeiden und wirklich nur verwenden, wenn Sie mehrere schwere Berechnungen auf mehreren CPUs ausführen möchten. In Windows beispielsweise wiegt ein Thread 12 KiByte.) Ich denke), in Linux wiegt ein Thread nur 4 KiByte, in Erlang/BEAM sogar nur 400 Byte. In .NET ist es 1 MiByte!)

431
Jörg W Mittag

Thread

Das Bare-Metal-Ding, das Sie wahrscheinlich nicht benötigen, können Sie wahrscheinlich eine LongRunning -Aufgabe verwenden und die Vorteile der in .NET Framework 4 (Februar 2002) enthaltenen TPL - Task Parallel Library nutzen. und höher (auch .NET Core).

Aufgaben

Abstraktion über den Fäden. Es verwendet den Thread-Pool (es sei denn, Sie geben die Aufgabe als LongRunning -Operation an. In diesem Fall wird für Sie ein neuer Thread unter der Haube erstellt.).

Thread-Pool

Wie der Name schon sagt: ein Pool von Threads. Behandelt das .NET Framework eine begrenzte Anzahl von Threads für Sie? Warum? Da es definitiv keine gute Idee ist, 100 Threads zu öffnen, um teure CPU-Vorgänge auf einem Prozessor mit nur 8 Kernen auszuführen. Das Framework verwaltet diesen Pool für Sie, verwendet die Threads erneut (ohne sie bei jedem Vorgang zu erstellen/zu beenden) und führt einige von ihnen parallel aus, sodass Ihre CPU nicht brennt.

OK, aber wann sollte man jeden verwenden?

Im Lebenslauf: Verwenden Sie immer Aufgaben.

Aufgabe ist eine Abstraktion, daher ist es viel einfacher zu verwenden. Ich rate Ihnen, immer zu versuchen, Aufgaben zu verwenden, und wenn Sie auf ein Problem stoßen, bei dem Sie einen Thread selbst behandeln müssen (wahrscheinlich 1% der Zeit), dann verwenden Sie Threads.

ABER sei dir bewusst, dass:

  • E/A-gebunden: Verwenden Sie für E/A-gebundene Vorgänge (Datenbankaufrufe, Lese-/Schreibvorgänge, API-Aufrufe usw.) keine normalen Tasks. LongRunning tasks ( oder Threads, wenn Sie müssen ). Denn die Verwendung von Tasks würde Sie zu einem Thread-Pool führen, in dem einige Threads beschäftigt sind und viele andere Tasks darauf warten, dass der Pool an die Reihe kommt.
  • CPU Bound: Verwenden Sie für CPU-gebundene Vorgänge einfach die normalen Tasks (die intern den Thread-Pool verwenden) und freuen Sie sich.
31

Sie können Task verwenden, um anzugeben, was Sie tun möchten. Fügen Sie dann dieses Task mit einem Thread hinzu. so dass Task in diesem neu erstellten Thread und nicht im GUI-Thread ausgeführt wird.

Verwenden Sie Task mit der TaskFactory.StartNew(Action action). Hier führen Sie einen Delegaten aus. Wenn Sie also keinen Thread verwendet haben, wird dieser im selben Thread (GUI-Thread) ausgeführt. Wenn Sie einen Thread erwähnen, können Sie diesen Task in einem anderen Thread ausführen. Dies ist eine unnötige Arbeit, da Sie den Stellvertreter direkt ausführen oder diesen Stellvertreter an einen Thread anhängen und diesen Stellvertreter in diesem Thread ausführen können. Also benutze es nicht. es ist nur unnötig. Wenn Sie beabsichtigen, Ihre Software zu optimieren, ist dies ein guter Kandidat, der entfernt werden sollte.

** Bitte beachten Sie, dass das Action ein delegate ist.

7
Gryphes

Zusätzlich zu den obigen Punkten wäre es gut zu wissen, dass:

  1. Eine Aufgabe ist standardmäßig eine Hintergrundaufgabe. Sie können keine Vordergrundaufgabe haben. Auf der anderen Seite kann ein Thread Hintergrund oder Vordergrund sein (verwenden Sie die IsBackground-Eigenschaft, um das Verhalten zu ändern).
  2. Im Thread-Pool erstellte Aufgaben recyceln die Threads, wodurch Ressourcen gespart werden. In den meisten Fällen sollten Aufgaben Ihre Standardauswahl sein.
  3. Wenn die Operationen schnell sind, ist es viel besser, eine Aufgabe anstelle eines Threads zu verwenden. Bei Operationen mit langer Laufzeit bieten Aufgaben gegenüber Threads keine großen Vorteile.
6
user2492339

Normalerweise verwende ich Task, um mit Winforms und einfachen Hintergrund-Workern zu interagieren, damit die Benutzeroberfläche nicht eingefroren wird. hier ein beispiel wenn ich lieber Task benutze

private async void buttonDownload_Click(object sender, EventArgs e)
{
    buttonDownload.Enabled = false;
    await Task.Run(() => {
        using (var client = new WebClient())
        {
            client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
        }
    })
    buttonDownload.Enabled = true;
}

VS

private void buttonDownload_Click(object sender, EventArgs e)
{
    buttonDownload.Enabled = false;
    Thread t = new Thread(() =>
    {
        using (var client = new WebClient())
        {
            client.DownloadFile("http://example.com/file.mpeg", "file.mpeg");
        }
        this.Invoke((MethodInvoker)delegate()
        {
            buttonDownload.Enabled = true;
        });
    });
    t.IsBackground = true;
    t.Start();
}

der Unterschied besteht darin, dass Sie nicht MethodInvoker und kürzeren Code verwenden müssen.

4
ewwink

Aufgabe ist wie eine Operation, die Sie ausführen möchten. Thread hilft dabei, diese Operation über mehrere Prozessknoten zu verwalten. Diese Aufgabe ist eine einfache Option, da das Threading zu einer komplexen Codeverwaltung führen kann
Ich werde vorschlagen, immer von MSDN (Best in World) zu lesen

Aufgabe

Thread

2
Saurabh