Creación de subprocesos: Task.Factory.StartNew vs new Thread ()


102

Estoy aprendiendo sobre las nuevas bibliotecas Threading y Parallel en .Net 4

En el pasado, crearía un nuevo hilo como este (como ejemplo):

DataInThread = new Thread(new ThreadStart(ThreadProcedure));
DataInThread.IsBackground = true;
DataInThread.Start();

Ahora puedo hacer:

Task t = Task.Factory.StartNew(() =>
{
   ThreadProcedure();
});

¿Cuál es la diferencia, si la hay?

Gracias


1
Deberá preocuparse un poco por cómo funciona el programador del grupo de subprocesos. Puede marcar una gran diferencia, pero todo depende de lo que realmente hagas dentro del hilo.
Hans Passant

Respuestas:


79

Existe una gran diferencia. Las tareas están programadas en ThreadPool e incluso podrían ejecutarse de forma síncrona si fuera apropiado.

Si tiene un trabajo en segundo plano de larga duración, debe especificarlo utilizando la opción de tarea correcta.

Debería preferir Task Parallel Library sobre el manejo explícito de subprocesos, ya que está más optimizado. También tienes más funciones como Continuación.


5
No, no es así. Simplemente inicia tareas. Esto podría poner la tarea en cola en el grupo de subprocesos o ejecutarla sincrónicamente. El TPL trata de liberarlo de administrar los subprocesos / concurrencia usted mismo y de usar lo mejor para su plataforma (como utilizar núcleos)
sanosdole

10
Existe la opción TaskCreationOptions.LongRunning que siempre creará otro hilo, pero el punto es ¿por qué necesita otro hilo? Si solo desea hacer algo en paralelo (Main hace algo mientras se ejecuta la tarea), es preferible dejar que una biblioteca optimizada decida cómo utilizar los recursos del sistema, como los subprocesos, para hacerlo de la manera más eficiente.
sanosdole

3
Este artículo de msdn describe cómo se programan las tareas. Cubre longrunning e inlining (ejecución sincrónica). msdn.microsoft.com/en-us/library/dd997402.aspx
sanosdole

2
@sming El punto es que desea procesar al mismo tiempo (sin bloquear la interfaz de usuario) no es que desee un nuevo hilo. ThreadPool no bloqueará el subproceso de la interfaz de usuario, pero administrará los subprocesos en segundo plano de manera mucho más eficiente de lo que podría hacerlo manualmente creando subprocesos. Ese es el proceso de cambio de mentalidad que introduce el TPL. No pienses en hilos, piensa en tareas concurrentes.
sanosdole

4
@sming Lo siento, esa oración fue un poco burda. La ejecución sincrónica de tareas se denomina inlining. Al programar una tarea en el threadpool (programador predeterminado) desde el Thread de la interfaz de usuario, no ocurrirá. Solo ocurrirá si el programador ambiental ('TaskScheduler.Current') es el mismo que el programador de una tarea a la que llamas '.Wait ()'. Como '.Wait ()' está bloqueando, bloqueará la interfaz de usuario de todos modos. Corto: No llame a esperar y no se ejecutará sincrónicamente.
sanosdole

74

La tarea le brinda todas las bondades de la API de tareas:

  • Agregar continuaciones ( Task.ContinueWith)
  • Esperando a que se completen varias tareas (todas o alguna)
  • Capturar errores en la tarea e interrogarlos más tarde
  • Capturando la cancelación (y permitiéndole especificar la cancelación para comenzar)
  • Potencialmente tener un valor de retorno
  • Usando await en C # 5
  • Mejor control sobre la programación (si va a ser de larga duración, dígalo cuando cree la tarea para que el programador de tareas pueda tenerlo en cuenta)

Tenga en cuenta que en ambos casos puede hacer que su código sea un poco más simple con conversiones de grupos de métodos:

DataInThread = new Thread(ThreadProcedure);
// Or...
Task t = Task.Factory.StartNew(ThreadProcedure);

8
+1. Me gustaría agregar que Threades de muy bajo nivel en comparación con Task(tengo una publicación de blog que entra en detalles). Estoy dando una charla sobre " cómo usar Tareas en el mundo real" en Grand Rapids DevDay . La charla se llama "Thread is Dead", porque ya no es necesario Thread(a menos que esté implementando a TaskScheduler).
Stephen Cleary

@StephenCleary, supongo que quiere decir que Threadestá muerto, cuando se trata de ser utilizado como hilo de fondo.
reflujo

1
@ebb: No, tomo la posición más fuerte descrita en mi primer comentario. No hay nada que se Threadpueda hacer (o BackgroundWorker) que no se pueda hacer de forma más elegante Tasky apropiada TaskScheduler.
Stephen Cleary

1
@StephenCleary, ¿Cómo crearías un hilo dedicado, sin usarlo Thread?
reflujo

4
@ebb: "Hilo dedicado" no me queda claro. Si quieres una Taskpara ejecutarse en un hilo específico, a continuación, utilizar un apropiado TaskScheduler- por ejemplo, AsyncContextThread. Sin embargo, esto generalmente no es necesario; el SynchronizationContext, ThreadPool, y ConcurrentExclusiveSchedulerPairlos programadores son suficientes para la mayoría de los programas.
Stephen Cleary

12

En el primer caso, simplemente está iniciando un nuevo hilo, mientras que en el segundo caso está entrando en el grupo de hilos.

El trabajo del grupo de subprocesos es compartir y reciclar subprocesos. Permite evitar perder unos milisegundos cada vez que necesitamos crear un nuevo hilo.

Hay varias formas de ingresar al grupo de subprocesos:

  • con el TPL (Task Parallel Library) como lo hizo
  • llamando a ThreadPool.QueueUserWorkItem
  • llamando a BeginInvoke en un delegado
  • cuando usas un BackgroundWorker

1

Su primer bloque de código le dice a CLR que cree un subproceso (digamos. T) para usted, que se puede ejecutar como fondo (use subprocesos del grupo de subprocesos al programar T). En resumen, le pide explícitamente a CLR que cree un hilo para que usted haga algo y llame al método Start () en el hilo para comenzar.

Su segundo bloque de código hace lo mismo pero delega (implícitamente traspaso) la responsabilidad de crear el hilo (en segundo plano, que de nuevo se ejecuta en el grupo de hilos) y el hilo de inicio a través del método StartNew en la implementación de Task Factory.

Esta es una diferencia rápida entre los bloques de código dados. Habiendo dicho eso, hay pocas diferencias detalladas que puede buscar en Google o ver otras respuestas de mis compañeros colaboradores.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.