web-dev-qa-db-fra.com

Concernant l'utilisation de Task.Start (), Task.Run () et Task.Factory.StartNew ()

Je viens de voir 3 routines concernant l’utilisation de TPL qui font le même travail; voici le code:

public static void Main()
{
    Thread.CurrentThread.Name = "Main";

    // Create a task and supply a user delegate by using a lambda expression. 
    Task taskA = new Task( () => Console.WriteLine("Hello from taskA."));
    // Start the task.
    taskA.Start();

    // Output a message from the calling thread.
    Console.WriteLine("Hello from thread '{0}'.", 
                  Thread.CurrentThread.Name);
    taskA.Wait();
}

public static void Main()
{
    Thread.CurrentThread.Name = "Main";

    // Define and run the task.
    Task taskA = Task.Run( () => Console.WriteLine("Hello from taskA."));

    // Output a message from the calling thread.
    Console.WriteLine("Hello from thread '{0}'.", 
                      Thread.CurrentThread.Name);
    taskA.Wait();
}

public static void Main()
{
    Thread.CurrentThread.Name = "Main";

    // Better: Create and start the task in one operation. 
    Task taskA = Task.Factory.StartNew(() => Console.WriteLine("Hello from taskA."));

    // Output a message from the calling thread.
    Console.WriteLine("Hello from thread '{0}'.", 
                    Thread.CurrentThread.Name);

    taskA.Wait();                  
}

Je ne comprends tout simplement pas pourquoi MS donne 3 façons différentes d'exécuter des tâches dans TPL parce qu'elles fonctionnent toutes de la même façon: Task.Start(), Task.Run() et Task.Factory.StartNew().

Dites-moi, est-ce que Task.Start(), Task.Run() et Task.Factory.StartNew() sont tous utilisés dans le même but ou ont-ils une signification différente?

Quand utiliser Task.Start(), quand utiliser Task.Run() et quand utiliser Task.Factory.StartNew()?

S'il vous plaît aidez-moi à comprendre leur utilisation réelle selon le scénario en détail avec des exemples, merci.

123
Mou

Task.Run est un raccourci pour Task.Factory.StartNew avec des arguments sécurisés spécifiques:

Task.Factory.StartNew(
    action, 
    CancellationToken.None, 
    TaskCreationOptions.DenyChildAttach, 
    TaskScheduler.Default);

Il a été ajouté à .Net 4.5 pour aider à l’utilisation de plus en plus fréquente de async et au déchargement du travail sur ThreadPool.

Task.Factory.StartNew (ajouté avec TPL dans .Net 4.0) est beaucoup plus robuste. Vous ne devriez l'utiliser que si Task.Run ne suffit pas, par exemple lorsque vous souhaitez utiliser TaskCreationOptions.LongRunning (bien que ce ne soit pas nécessaire lorsque le délégué est asynchrone. Plus d'informations à ce sujet sur mon blog: LongRunning Est inutile pour Task.Run With async-wait ). Plus d'informations sur Task.Factory.StartNew dans Task.Run vs Task.Factory.StartNew

Ne créez jamais une Task et appelez Start() à moins que vous ne trouviez une très bonne raison de le faire. Il ne doit être utilisé que si vous avez une partie qui doit créer des tâches mais ne les planifiez pas, et une autre partie qui planifie sans créer. Ce n'est presque jamais une solution appropriée et pourrait être dangereux. Plus dans "Task.Factory.StartNew" vs "nouvelle tâche (...). Début"

En conclusion, utilisez principalement Task.Run, utilisez Task.Factory.StartNew si vous devez et n'utilisez jamais Start.

148
i3arnon