2011-10-13 6 views
7

Cuando crea un Task al especificar TaskCreationOptions.LongRunning, se crea un nuevo subproceso específico para la tarea. Si no especifica el TaskCreationOptions.LongRunning, entonces se utiliza el subproceso de subprocesos.¿Soy responsable de la limpieza después de una tarea creada con el indicador TaskCreationOptions.LongRunning?

Corrígeme si me equivoco pero si se utiliza el subproceso de hebras no es necesario dispose() la tarea (siempre que no haya utilizado ningún objeto de sincronización dentro de la tarea, como Wait() en una tarea secundaria).

Si este es el caso, ¿soy responsable de limpiar el hilo adicional creado al usar la bandera TaskCreationOptions.LongRunning?

Si es así es el siguiente un patrón aceptable:

var task = Task.Factory.StartNew(() => {...}, TaskCreationOptions.LongRunning); 

task.ContinueWith(x => task.Dispose()); 

Aviso cómo, la ContinueWith no tiene TaskContinuationOptions.LongRunning, por lo que debe utilizar el subprocesos.

Dicho esto, sin embargo, he leído que el hilo que mueve el estado de la tarea a Completed, Faulted o Cancelled tiene un alto cambio de ejecución de la continuación.

Si alguien pudiera arrojar algo de luz sobre esto, realmente lo agradecería.

Respuesta

5

TaskContinuationOptions.LongRunning es un indicio al Grupo de fábrica/programador, las cosas no son tan fijos como lo retratan.

Esperaría que el ContinueWith se ejecutara en el mismo hilo (longRunning), que puede o no ejecutarse en el ThreadPool.

Y por lo que yo sé, la limpieza de Tareas es automática, así que no me molestaría con Dispose() aquí.

+0

Gracias por aclarar que la bandera es una pista en lugar de una regla fija. En cuanto a la limpieza automática de Tareas, realmente espero que este sea el caso, ya que hace que trabajar con ellos sea mucho más fácil. Tengo +1 para la información, pero esperaré para ver si alguien más tiene información adicional para poner sobre la mesa. ¡Espero estar aceptando tu respuesta pronto! Gracias de nuevo. – InvertedAcceleration

6

Definitivamente no llame al Dispose() en una continuación: ¿cuándo va a disponer de la tarea de continuación?

AFAIK, la única razón por la cual Task es desechable es limpiar el asa de espera creada si espera la tarea. Si no esperas la tarea, el identificador de espera nunca se creará. En cualquier caso, el finalizador desaparecerá eventualmente.

Además, si un nuevo hilo es creado por el Grupo, se va a limpiar después de sí mismo.

2

No estoy seguro acerca de la eliminación de Tasks creada con la opción LongRunning, pero hay algunas cosas que le vienen a la mente sobre el patrón que ha mostrado.

  1. Como se muestra inicial de larga duración Task no se observa lo que significa que si la operación arroja un Exception por cualquier razón, entonces se va a terminar siendo re-lanzado en el finalizador que haría que el proceso se bloquee.
  2. La documentación del Task dice que no debe llamar al Dispose a menos que el Task haya finalizado.Así que realmente debería verificar que Task se complete en la continuación si va a llamar a disponer.
  3. En realidad está llamando al Dispose en el Task devuelto por ContinueWith, no por la tarea original de larga ejecución.

Por lo que podría hacer algo como:

var task = Task.Factory.StartNew(() => {...}, TaskCreationOptions.LongRunning) 
       .ContinueWith(x => 
    if(x.IsFaulted) 
    { 
     x.Exception.Handle(_ => true); //just an example, you'll want to handle properly 
    } 
    else if(x.IsCompleted) 
    { 
     //do something with the result, if necessary 
     x.Dispose()); 
    }); 

En última instancia, creo que es más importante observar el Task que a Dispose ella.

+0

Gracias por la información. Además, he actualizado el código anterior para reflejar su comentario sobre que eliminé la tarea incorrecta. Escribí el código rápidamente en el recuadro de preguntas porque pensé que era lo suficientemente directo - jaja, imagina que haría un error tipográfico. En realidad, quise preguntar sobre el código de la manera que es ahora, donde se llama a disponer de la tarea original que se creó y no de la continuación. Tan buena captura. – InvertedAcceleration

Cuestiones relacionadas