Я только что видел 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()
?
Пожалуйста, помогите мне понять их реальное использование в соответствии со сценарием подробно с примерами, спасибо.
Task.Run
- может быть, это ответит на ваш вопрос;)Task.Start
это действительно полезно.Ответы:
Task.Run
это сокращение отTask.Factory.StartNew
конкретных безопасных аргументов:Он был добавлен в .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
.источник
Task.Start
имеет место для наследования типов.Краткий ответ :
Если вы не используете вложенные дочерние задачи и всегда хотите, чтобы ваши задачи выполнялись в пуле потоков , лучше использовать
Task.Run
.Длинный ответ:
Task.Run
иTask.Factory.StartNew
оба обеспечивают поддержку для создания и планирования объектов Task, поэтому нам не нужно создаватьTask
и вызыватьStart()
Эквивалентно:
А также
Эквивалентно:
Task.Run
использует,TaskCreationOptions.DenyChildAttach
что означает, что дочерние задачи не могут быть прикреплены к родительскому объекту, и он использует,TaskScheduler.Default
что означает, что тот, который выполняет задачи в пуле потоков, всегда будет использоваться для выполнения задач.Task.Factory.StartNew
использует,TaskScheduler.Current
что означает планировщик текущего потока, это может быть,TaskScheduler.Default
но не всегда.источник