2012-09-03 19 views
7

que tienen las siguientes líneas en mi código:¿Cómo verificar que todas las tareas se hayan completado correctamente?

var taskA = Task.Factory.StartNew(WorkA); 
    var taskB = Task.Factory.StartNew(WorkB); 
    var allTasks = new[] { taskA, taskB }; 

    Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork(), TaskContinuationOptions.OnlyOnRanToCompletion); 

Pero cuando corro esto, me sale el siguiente error:

It is invalid to exclude specific continuation kinds for continuations off of multiple tasks.

que es causada por la opción TaskContinuationOptions.OnlyOnRanToCompletion.

Mi pregunta es cómo comprobar que todas las tareas han hecho su trabajo correctamente (todos los estados de las tareas se RanToCompletion) y luego hacer FinalWork()? Mientras tanto, la aplicación realiza otras tareas.

+0

¿Qué desea hacer si algunos de los 'Task's fallan? – svick

+0

Si algunos de los 'Tareas' fallan, nada debería hacerse. – Zen

Respuesta

11

Según @Peter Ritchie y @Ben McDougall responde que encontré una solución. He modificado mi código mediante la eliminación de variables redundantes y tasksTaskContinuationOptions.OnlyOnRanToCompletion

var taskA = Task.Factory.StartNew(WorkA); 
var taskB = Task.Factory.StartNew(WorkB); 
var allTasks = new[] { taskA, taskB }; 
Task.Factory.ContinueWhenAll(allTasks, FinalWork); 

Dónde FinalWork es:

private static void FinalWork(Task[] tasks) 
{ 
    if (tasks.All(t => t.Status == TaskStatus.RanToCompletion)) 
    { 
     // do "some work" 
    } 
} 

Si todo tasks tienen estatus RanToCompletion, "algún trabajo" se hará. Se realizará inmediatamente después de que se hayan completado todas las tareas y no bloqueará la tarea principal. Si cancelo al menos una de las tareas, no se hará nada.

Alternativamente, usted puede hacer esto,

var taskA = Task.Factory.StartNew(WorkA); 
var taskB = Task.Factory.StartNew(WorkB); 
var allTasks = new[] { taskA, taskB }; 
var continuedTask = Task.WhenAll(allTasks).ContinueWith((antecedent) => { /*Do Work*/ }, TaskContinuationOptions.OnlyOnRanToCompletion)); 
3

No ha proporcionado ningún código que haga algo con alguna de las tareas que se ejecutaron hasta su finalización (se ignora su variable tasks). Obtendría el mismo resultado si simplemente eliminara TaskContinuationOptions.OnlyOnRanToCompletion. es decir, si podría usa ContinueWhenAll con TaskContinuationOptions.OnlyOnRanToCompletion, no se invocará su continuación hasta que todas las tareas se hayan completado o hayan fallado. Si no hace nada solo con las tareas completadas, es lo mismo que Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork());

Si hay algo más específico que desea hacer, proporcione los detalles para que alguien pueda ayudarlo.

+0

Sí, tienes razón. Ahora veo que las 'tareas' variables son redundantes. Toda la información sobre los estados de las tareas se puede pasar a la función a través de la variable 'allTasks'. – Zen

1

Para responder a la pregunta real que usted plantea:

My question is how to check that all tasks have done their work properly (all tasks statuses are RanToCompletion) and then do FinalWork()? In the meantime, the application performs other tasks.

al menos eso es lo que he leído como la cuestión comprobar el siguiente código:

var taskA = Task.Factory.StartNew(WorkA); 
    var taskB = Task.Factory.StartNew(WorkB); 
    var allTasks = new[] { taskA, taskB }; 

    taskA.Wait(); 
    taskB.Wait(); 

    if (taskA.Status == TaskStatus.RanToCompletion && taskB.Status == TaskStatus.RanToCompletion) 
     Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork()); 
    else 
     //do something 

En realidad respondido a la pregunta a sí mismo con su pregunta si quisiste decir eso.

+0

Gracias por su respuesta.Lamentablemente, esta solución está bloqueando la tarea principal mediante el método 'Tarea.Espera' – Zen

+0

@Zen Agregué algunas Tareas entre la declaración de las tareas y el Wait, y se ejecutan muy bien con nuestro bloqueo. Examinaremos tu problema nuevamente más tarde. –

+0

@Zen: Agregué una nueva clase y contenía un subproceso y todo funciona bien. Nada está bloqueado, todo está funcionando sin problemas. Necesitaré más información sobre tu problema ya que no tengo ninguna dificultad hasta ahora. Básicamente se agregó una Clase que inicia un hilo en el constructor y lo agrega antes de las tareas: 'código' var taskC = Task.Factory.StartNew (WorkC); JustAnotherThread jt = new JustAnotherThread(); var taskA = Task.Factory.StartNew (WorkA); 'code' –

Cuestiones relacionadas