2015-04-17 3 views
99

Я только видел 3 дня относительно использования TPL, который делает ту же работуЧто касается использования Task.Start(), Task.Run() и Task.Factory.StartNew()

здесь код

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()?

Пожалуйста, помогите мне понять их реальное использование по сценарию в деталях с примерами, спасибо.

+0

Существует [старая статья, объясняющая это здесь] (http://blogs.msdn.com/b/pfxteam/archive/2010/06/13/10024153.aspx) и [здесь для более новой 'Task.Run '] (http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx) - возможно, это ответит на ваш вопрос;) – Carsten

+0

[Здесь] (http://stackoverflow.com/a/21427264/1768303) является примером того, где 'Task.Start' действительно полезен. – Noseratio

ответ

108

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 Is Useless For Task.Run With async-await). Подробнее о Task.Factory.StartNew в Task.Run vs Task.Factory.StartNew

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

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

+2

u сказал: «Никогда не создавайте задачу и не вызывайте« Пуск »()« перенаправляйте меня на любую хорошую запись, которая покажет, что может вызвать Task.Start(). Мне нужны детали, потому что вы говорите, чтобы избежать этого. Спасибо за ответ. – Mou

+0

@Mou У меня уже есть ... – i3arnon

+0

r u говоря об этой ссылке http://blogs.msdn.com/b/pfxteam/archive/2010/06/13/10024153.aspx ?? – Mou

0

В дополнение к Ответу, вы не должны создавать задачу из конструктора без веской причины. TPL берет на себя большую осторожность при синхронизации и параллелизме. Он скрывает эту сложность от клиентского кода. Если вы создадите задачу и запустите ее, вам нужно подумать о синхронизации и параллелизме, которые, очевидно, трудно обрабатывать.

Смежные вопросы