Acabo de ver 3 rutinas con respecto al uso de TPL que hacen el mismo trabajo; Aquí está el 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();
}
Simplemente no entiendo por qué MS da 3 métodos diferentes para ejecutar trabajos en TPL, ya que todo el trabajo de la misma: Task.Start()
, Task.Run()
y Task.Factory.StartNew()
.
Dime, están Task.Start()
, Task.Run()
y Task.Factory.StartNew()
todos utilizados para el mismo propósito o tienen un significado diferente?
¿Cuándo se debe usar Task.Start()
, cuándo se debe usar Task.Run()
y cuándo se debe usar Task.Factory.StartNew()
?
Ayúdenme a comprender su uso real según el escenario en gran detalle con ejemplos, gracias.
Task.Run
, tal vez esto responderá a su pregunta;)Task.Start
es realmente útil.Respuestas:
Task.Run
es una abreviaturaTask.Factory.StartNew
con argumentos seguros específicos:Se agregó en .Net 4.5 para ayudar con el uso cada vez más frecuente
async
y la descarga de trabajo en elThreadPool
.Task.Factory.StartNew
(agregado con TPL en .Net 4.0) es mucho más robusto. Solo debe usarlo siTask.Run
no es suficiente, por ejemplo, cuando quiere usarloTaskCreationOptions.LongRunning
(aunque es innecesario cuando el delegado es asíncrono. Más sobre eso en mi blog: LongRunning es inútil para la tarea. Ejecutar con async-wait ). Más sobreTask.Factory.StartNew
en Task.Run vs Task.Factory.StartNewNunca cree una
Task
llamada aStart()
menos que encuentre una muy buena razón para hacerlo. Solo debe usarse si tiene alguna parte que necesita crear tareas pero no programarlas y otra parte que programa sin crear. Esa casi nunca es una solución adecuada y podría ser peligrosa. Más en "Task.Factory.StartNew" frente a "new Task (...). Start"En conclusión, use principalmente
Task.Run
, useTask.Factory.StartNew
si debe y nunca useStart
.fuente
Task.Start
tiene su lugar para heredar tipos principalmente.Respuesta corta :
Si no está utilizando tareas infantiles anidadas y siempre desea que sus tareas se ejecuten en Thread Pool , es mejor usarlas
Task.Run
.Respuesta larga:
Task.Run
yTask.Factory.StartNew
ambos brindan soporte para crear y programar objetos de Tarea para que no necesitemos crear unaTask
llamadaStart()
Es equivalente a:
Y
Es equivalente a:
Task.Run
usa loTaskCreationOptions.DenyChildAttach
que significa que las tareas de los niños no se pueden adjuntar a los padres y usa loTaskScheduler.Default
que significa que la que ejecuta tareas en Thread Pool siempre se usará para ejecutar tareas.Task.Factory.StartNew
utiliza loTaskScheduler.Current
que significa planificador del subproceso actual, puede serTaskScheduler.Default
pero no siempre.fuente