it-roy-ru.com

Относительно использования Task.Start (), Task.Run () и Task.Factory.StartNew ()

Я только что видел 3 процедуры, касающиеся использования TPL, которые выполняют ту же работу; вот код:

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 дает 3 разных способа запуска заданий в TPL, потому что все они работают одинаково: 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 (добавлен с TPL в .Net 4.0) гораздо надежнее. Вы должны использовать его только в том случае, если Task.Run недостаточно, например, когда вы хотите использовать TaskCreationOptions.LongRunning (хотя в этом нет необходимости, когда делегат асинхронный. Подробнее об этом в моем блоге: LongRunning бесполезен для Task.Run With async -await ). Подробнее о Task.Factory.StartNew в Task.Run vs Task.Factory.StartNew

Никогда не создавайте Task и вызывайте Start(), если вы не найдете для этого очень веских причин. Его следует использовать, только если у вас есть какая-то часть, которая должна создавать задачи, но не запланировать их, а другая часть, которая планирует без создания. Это почти никогда не является подходящим решением и может быть опасным. Больше в "Task.Factory.StartNew" против "новой задачи (...). Start"

В заключение, в основном используйте Task.Run, используйте Task.Factory.StartNew, если вы должны и никогда не используете Start.

143
i3arnon