web-dev-qa-db-fra.com

Quelle est la difference entre task et thread?

En C # 4.0, nous avons Task dans l'espace de noms System.Threading.Tasks. Quelle est la vraie différence entre Thread et Task. J'ai fait quelques exemples de programme (aide pris de MSDN) pour mon propre apprentissage avec

Parallel.Invoke 
Parallel.For 
Parallel.ForEach 

mais ayez beaucoup de doutes car l’idée n’est pas aussi claire.

Dans un premier temps, j'ai cherché dans Stackoverflow un type de question similaire, mais le titre de la question ne correspond peut-être pas au même résultat. Si quelqu'un sait que le même type de question a été posté ici plus tôt, veuillez indiquer la référence du lien.

355
user372724

Une tâche est quelque chose que vous voulez faire.

Un fil est l'un des nombreux ouvriers possibles qui effectuent cette tâche.

En termes .NET 4.0, Task représente une opération asynchrone. Les threads sont utilisés pour terminer cette opération en scindant le travail en morceaux et en affectant des threads séparés.

295
Mitch Wheat

En termes d’informatique, un Task est un futur ou une promesse . (Certaines personnes utilisent ces deux termes de façon synomyme, d'autres les utilisent différemment, personne ne peut s'accorder sur une définition précise .) Fondamentalement, un Task<T> " promet "de te rendre un T, mais pas maintenant chérie, je suis un peu occupé, pourquoi ne reviendrais-tu pas plus tard?

Un Thread est un moyen de remplir cette promesse. Mais chaque Task n'a pas besoin d'un tout nouveau Thread. (En fait, créer un thread est souvent indésirable, car cela coûte beaucoup plus cher que de réutiliser un thread existant du pool de threads. Plus d'informations à ce sujet dans un instant.) Si la valeur que vous attendez provient du système de fichiers ou d'un fichier. base de données ou le réseau, il n’est pas nécessaire pour un thread de s’asseoir et d’attendre les données lorsqu’il peut traiter d’autres requêtes. Au lieu de cela, le Task peut enregistrer un rappel pour recevoir la ou les valeurs lorsqu'il est prêt.

En particulier, le Task ne fait pas pourquoi il est qu'il faut beaucoup de temps pour renvoyer la valeur. Il se peut que le calcul prenne beaucoup de temps ou que l'extraction prenne beaucoup de temps. Dans le premier cas, vous utiliseriez un Thread pour exécuter un Task. (Dans .NET, les threads coûtent très cher, vous devez donc généralement les éviter autant que possible et ne les utiliser que si vous souhaitez exécuter plusieurs calculs lourds sur plusieurs processeurs. Par exemple, sous Windows, un thread pèse 12 ki ( Je pense), sous Linux, un fil ne pèse que 4 Ko, en Erlang/BEAM, même 400 octets. En .NET, 1 MiByte!)

431
Jörg W Mittag

Thread

La solution simple, vous n'avez probablement pas besoin de l'utiliser, vous pouvez probablement utiliser une tâche LongRunning et profiter des avantages de la bibliothèque TPL - Task Parallel Library, incluse dans .NET Framework 4 (février 2002) et ci-dessus (également .NET Core).

Les tâches

Abstraction au-dessus des fils. Il tilise le pool de threads (sauf si vous spécifiez la tâche comme une opération LongRunning, si tel est le cas, un nouveau thread est créé sous le capot pour vous).

Pool de threads

Comme son nom l'indique: un pool de threads. Le framework .NET gère-t-il un nombre limité de threads? Pourquoi? Car ouvrir 100 threads pour exécuter des opérations de processeur coûteuses sur un processeur avec seulement 8 cœurs n'est certainement pas une bonne idée. La structure maintiendra ce pool pour vous, en réutilisant les threads (sans les créer/les tuer à chaque opération) et en les exécutant en parallèle, de manière à ce que votre processeur ne brûle pas.

OK, mais quand utiliser chacun d'eux?

En résumé: utilisez toujours des tâches.

La tâche est une abstraction, elle est donc beaucoup plus facile à utiliser. Je vous conseille de toujours essayer d'utiliser des tâches et si vous rencontrez un problème qui vous oblige à gérer un fil par vous-même (probablement 1% du temps), utilisez-le.

MAIS être conscient que:

  • I/O Bound: pour les opérations liées aux E/S (appels de base de données, lecture/écriture de fichiers, appels d'API, etc.), évitez d'utiliser des tâches normales, utilisez LongRunning tâches ( ou des discussions si vous avez besoin de ). Parce que l'utilisation de tâches vous mènerait à un pool de threads avec quelques threads occupés et de nombreuses autres tâches attendant son tour pour prendre le pool.
  • CPU Bound: Pour les opérations liées à la CPU, utilisez simplement les tâches normales (qui utilisera en interne le pool de threads) et soyez heureux.
31
fabriciorissetto

Vous pouvez utiliser Task pour spécifier ce que vous voulez faire, puis associez ce Task à un Thread. de sorte que Task soit exécuté dans le Thread nouvellement créé plutôt que sur le fil de l'interface graphique.

Utilisez Task avec la TaskFactory.StartNew(Action action). Ici, vous exécutez un délégué, donc si vous n'utilisiez aucun thread, il serait exécuté dans le même thread (thread d'interface graphique). Si vous mentionnez un fil, vous pouvez exécuter cette Task dans un autre fil. C'est un travail inutile car vous pouvez directement exécuter le délégué ou attacher ce délégué à un thread et exécuter ce délégué dans ce thread. Alors ne l'utilisez pas. c'est juste inutile. Si vous avez l’intention d’optimiser votre logiciel, c’est un bon candidat à supprimer.

** Veuillez noter que la Action est une delegate.

7
Gryphes

En plus des points ci-dessus, il serait bon de savoir que:

  1. Une tâche est par défaut une tâche en arrière-plan. Vous ne pouvez pas avoir de tâche de premier plan. D'autre part, un fil peut être à l'arrière-plan ou à l'avant-plan (utilisez la propriété IsBackground pour modifier le comportement).
  2. Les tâches créées dans le pool de threads recyclent les threads, ce qui permet d'économiser des ressources. Donc, dans la plupart des cas, les tâches devraient être votre choix par défaut.
  3. Si les opérations sont rapides, il est préférable d'utiliser une tâche au lieu d'un thread. Pour les opérations de longue durée, les tâches n'offrent pas beaucoup d'avantages par rapport aux threads.
6
user2492339

J'utilise habituellement Task pour interagir avec Winforms et un simple arrière-plan pour éviter que l'interface utilisateur ne soit figée. voici un exemple où je préfère utiliser Task

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;
}

CONTRE

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();
}

la différence est que vous n'avez pas besoin d'utiliser MethodInvoker et un code plus court.

4
ewwink

La tâche est comme une opération que vous souhaitez effectuer. Thread aide à gérer ces opérations via plusieurs nœuds de processus. tâche est une option légère, car le threading peut conduire à une gestion de code complexe
Je suggère de lire toujours à partir de MSDN (Best in world)

tâche

Fil

2
Saurabh