Что касается использования 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()
?
Пожалуйста, помогите мне понять их реальное использование в соответствии со сценарием очень подробно с примерами, спасибо.
Ответы
Ответ 1
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. Запустить с асинхронным ожиданием). Подробнее о Task.Factory.StartNew
в Task.Run vs Task.Factory.StartNew
Никогда не создавайте Task
и не звоните Start()
, если вы не найдете для этого очень веских причин. Его следует использовать, только если у вас есть какая-то часть, которая должна создавать задачи, но не запланировать их, а другая часть, которая планирует без создания. Это почти никогда не подходящее решение и может быть опасным. Подробнее о "Task.Factory.StartNew" и "новой задаче (...). Запуск"
В заключение, в основном используйте Task.Run
, используйте Task.Factory.StartNew
, если вы должны и никогда не используете Start
.
Ответ 2
В дополнение к Ответу, вы не должны создавать задачу из конструктора без веской причины. TPL берет на себя большую осторожность при синхронизации и concurrency. Скрыть эту сложность от клиентского кода. Если вы создадите задачу и запустите ее, вам нужно подумать о синхронизации и concurrency, которые, очевидно, трудно обрабатывать.