Acabei de ver três rotinas sobre o uso do TPL que fazem o mesmo trabalho; aqui está o código:
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();
}
Eu só não entendo por que MS dá 3 maneiras diferentes de executar trabalhos em TPL porque todos eles trabalham o mesmo: Task.Start()
, Task.Run()
e Task.Factory.StartNew()
.
Diga-me, são Task.Start()
, Task.Run()
e Task.Factory.StartNew()
todos utilizados para a mesma finalidade ou eles têm um significado diferente?
Quando se deve usar Task.Start()
, quando se deve usar Task.Run()
e quando se deve usar Task.Factory.StartNew()
?
Por favor, ajude-me a entender seu uso real conforme o cenário em detalhes, com exemplos, obrigado.
Task.Run
- talvez isso responda à sua pergunta;)Task.Start
é realmente útil.Respostas:
Task.Run
é uma abreviação deTask.Factory.StartNew
argumentos seguros específicos:Foi adicionado no .Net 4.5 para ajudar no uso cada vez mais frequente
async
e no trabalho de descarregamento para oThreadPool
.Task.Factory.StartNew
(adicionado com o TPL no .Net 4.0) é muito mais robusto. Você deve usá-lo apenas seTask.Run
não for suficiente, por exemplo, quando quiser usá-TaskCreationOptions.LongRunning
lo (embora seja desnecessário quando o delegado for assíncrono. Mais sobre isso no meu blog: LongRunning é inútil para tarefas.Executar com async-waitit ). Mais sobreTask.Factory.StartNew
em Task.Run vs Task.Factory.StartNewNunca crie uma
Task
chamada e aStart()
menos que encontre um motivo extremamente bom para fazê-lo. Só deve ser usado se você tiver uma parte que precise criar tarefas, mas não agendá-las, e outra parte que agendar sem criar. Isso quase nunca é uma solução apropriada e pode ser perigoso. Mais em "Task.Factory.StartNew" vs "new Task (...). Start"Em conclusão, principalmente use
Task.Run
, useTask.Factory.StartNew
se você precisar e nunca useStart
.fonte
Task.Start
tem seu lugar para herdar tipos principalmente.Resposta curta :
Se você não estiver usando tarefas filho aninhadas e sempre desejar que suas tarefas sejam executadas no Pool de Threads , é melhor usá-lo
Task.Run
.Resposta longa:
Task.Run
eTask.Factory.StartNew
ambos fornecem suporte para criar e agendar objetos de tarefas, para que não precisemos criarTask
e chamarStart()
É equivalente a:
E
É equivalente a:
Task.Run
usa oTaskCreationOptions.DenyChildAttach
que significa que as tarefas dos filhos não podem ser anexadas ao pai e usa oTaskScheduler.Default
que significa que aquele que executa tarefas no Conjunto de Threads sempre será usado para executar tarefas.Task.Factory.StartNew
usa oTaskScheduler.Current
que significa planejador do encadeamento atual, pode ser,TaskScheduler.Default
mas nem sempre.fonte