web-dev-qa-db-ja.com

Task.Start()、Task.Run()およびTask.Factory.StartNew()の使用に関して

同じ仕事をするTPLの使用に関する3つのルーチンを見ました。コードは次のとおりです。

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

MSがTPLでジョブを実行する3つの異なる方法を提供している理由がわかりません。これらはすべて、Task.Start()Task.Run()Task.Factory.StartNew()が同じように機能するためです。

Task.Start()Task.Run()、およびTask.Factory.StartNew()はすべて同じ目的で使用されていますか、それとも意味が異なりますか?

Task.Start()を使用する必要がある場合、Task.Run()を使用する必要がある場合、およびTask.Factory.StartNew()を使用する必要がある場合

シナリオごとに実際の使用法を理解するのを助けてください、例を挙げて感謝します。

119
Mou

Task.Runは、特定の安全な引数を持つTask.Factory.StartNewの短縮形です。

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

.NET 4.5では、asyncの使用頻度が増え、ThreadPoolへの作業がオフロードされるのを支援するために追加されました。

Task.Factory.StartNew(.Net 4.0のTPLで追加)ははるかに堅牢です。 Task.Runで十分でない場合、たとえばTaskCreationOptions.LongRunningを使用する場合にのみ使用する必要があります(ただし、デリゲートが非同期の場合は不要です。詳細については、ブログで: LongRunning Is Useless For Task.Run With async -await )。 Task.Run vs Task.Factory.StartNewTask.Factory.StartNewの詳細

特別な理由がない限り、Taskを作成してStart()を呼び出さないでください。タスクを作成する必要があるが、タスクをスケジュールしない一部と、作成せずにスケジュールする別の部分がある場合にのみ使用してください。それはほとんど適切な解決策ではなく、危険な場合があります。 "Task.Factory.StartNew" vs "new Task(...)。Start" の詳細

結論として、主にTask.Runを使用し、Startを使用する必要があり、使用しない場合はTask.Factory.StartNewを使用します。

143
i3arnon