2011-07-23 11 views
7

he encontrado una paz de código en la web y han modificado un poco para ver cómo funciona, pero ahora tengo un problema con ContinueWhenALl ya que no espera todas las tareas para ser terminadasContinueWhenAll no esperar a que todas las tareas para completar

List<Task> tasks = new List<Task>(); 
for (int i = 0; i < 20; i++) 
{ 
    int j = i; 
    var compute = Task.Factory.StartNew(() => results.Add(DoSomething(j))); 
    tasks.Add(compute); 
} 

Estoy usando este código para agregar todas las tareas a la lista. DoSomething función calcula algunos resultados y los añade a BlockingCollection tengo otra función de visualización que escribe todos los resultados agregados de BlockingCollection a la consola

He utilizado este código para esperar a que todas las tareas para completar, pero parece que no espera como el programa muestra el mensaje estándar "Presione cualquier tecla para continuar" unos pocos milisegundos después de que se haya iniciado el programa. (Se debe tener ~ 20 segundos para el programa para completar)

Task.Factory.ContinueWhenAll(tasks.ToArray(), result => results.CompleteAdding()); 

Sin embargo si añado Task.WaitAll(consume) al final del programa, el programa funciona bien

var consume = Task.Factory.StartNew(() => display(results)); 
//results = BlockingCollection that I mentioned 

lo que entiendo que el programa no tendrá suficiente Es hora de mostrar todos los resultados de BlockingCollection pero aún tiene más el tiempo suficiente para mostrar algunos mientras espera a que se completen todas las tareas

¿Podría alguien explicarme por qué Task.Factory.ContinueWhenAll no espera todos los resultados para se calcula y el programa llega a su fin al igual que no hay esa línea de código en el programa (después de unos pocos milisegundos)

Respuesta

15

Task.Factory.ContinueWhenAll no es un método de bloqueo; lo que realmente va a comenzar una nueva tarea que se activa únicamente cuando todas las tareas previstas completa no la ejecución, por lo que es normal ver un mensaje se ha iniciado sólo unos milisegundos después de programa, porque no lo hará bloque a su espera principal de las tareas para terminar. De msdn:

crea una tarea de continuación que se inició después de la finalización de un conjunto de tareas previstas.

Cuando el bloque se Task.WaitAll a la persona que llama a la espera de todas las tareas previstas para completar la ejecución.

+0

"a la finalización de un conjunto de tareas previstas" eso es exactamente lo que estoy hablando, no debería crear una nueva tarea hasta que todas las tareas de la lista han completado su trabajo. Lo único confuso aquí es si el programa espera "en esa línea" o el programa pasa a la siguiente línea y lanza una nueva tarea después de completar todas las tareas. – Dan

+0

@ Dan: Cuando 'ContinueWhenAll' El programa no' espera en que line' su lugar, se pasa a la siguiente línea y al mismo tiempo crear una nueva tarea que no va a funcionar hasta que las tareas previstas acabados. pero el 'WaitAll' _esperará en esa línea_" bloque "hasta que todas las tareas proporcionadas completen su ejecución. –

+0

parece que esto no es realmente cierto, echar un vistazo a su enlace http://blogs.msdn.com/b/csharpfaq/archive/2010/06/18/parallel-programming-task-schedulers-and-synchronization-context .aspx? PageIndex = 2 y encontrará una parte que dice que ya he usado el método ContinueWhenAll que espera a que finalice una serie de tareas. – Dan

Cuestiones relacionadas