2011-01-12 17 views
9

Casi toda la documentación que he visto sobre el uso de C. 4.0 Task.Factory.StartNew indica que para esperar a que se complete la tarea, necesita esperar. Pero mi prueba inicial muestra que no es necesario. ¿Alguien más puede darme una confirmación sobre esto? Tengo curiosidad de por qué tantas referencias en línea e impresas dicen que debes llamar a Wait.¿Es necesario esperar() después de usar Task.Factory.StartNew()?

Aquí hay una aplicación de consola simple que muestra que no necesito la instrucción Wait, así que la comenté. Ya sea que comente o no el tsk.Wait(), el resultado es el mismo.

Resultados previstos en todos los casos es el siguiente:

 
Main thread starting. 
After running MyTask. The result is True 
After running SumIt. The result is 1 
Main thread ending. 

El código:

class Program 
{ 
    // A trivial method that returns a result and takes no arguments. 
    static bool MyTask() 
    { 
     Thread.Sleep(2000); 
     return true; 
    } 

    // This method returns the summation of a positive integer 
    // which is passed to it. 
    static int SumIt(object v) 
    { 
     int x = (int)v; 
     int sum = 0; 
     for (; x > 0; x--) 
      sum += x; 
     return sum; 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine("Main thread starting."); 
     // Construct the first task. 
     Task<bool> tsk = Task<bool>.Factory.StartNew(() => MyTask()); 
     // I found this Wait statement to be completely unnecessary. 
     //tsk.Wait(); 
     Console.WriteLine("After running MyTask. The result is " + 
     tsk.Result); 
     // Construct the second task. 
     Task<int> tsk2 = Task<int>.Factory.StartNew(() => SumIt(1)); 
     Console.WriteLine("After running SumIt. The result is " + 
     tsk2.Result); 
     tsk.Dispose(); 
     tsk2.Dispose(); 
     Console.WriteLine("Main thread ending."); 
     Console.ReadLine(); 
    } 
} 

Respuesta

19

Si solo quiere esperar a que termine la tarea, el curso de acción recomendado es llamar al .Wait(). Para un Task (en comparación con un Task<T>) esta es la única opción.

Para una Task<T>, sin embargo, también hay .Result, que también espera, y eso es lo que está utilizando. Entonces, en su caso, no es necesario llamar al .Wait().

+0

Gracias, Timwi. Tuve un pedo cerebral y no noté que estaba usando la Tarea en lugar de Tarea. ¡Ahora tiene sentido! –

+0

@tambui: ¿qué le parece marcar esto como una respuesta? – stackoverflowuser

+0

@stackoverflowuser: Lo siento, no sabía cómo hacerlo. Hecho ahora. –

1

Dado que, según this, el acceso a la Value del Task asegura que la tarea se ha completado, usted' Está bien que no sea necesario.

+0

Eso es correcto. Gracias, Jacob! Mi error fue que olvidé que estaba usando la Tarea en lugar de Tarea. –

1

Como dijo Timwi, .Result también espera. Como está utilizando tsk.Result en la llamada Console.WriteLine, está haciendo la espera como un efecto secundario.

También depende del tiempo que tarde en completar la tarea. Si es muy corto, es posible que no se dé cuenta de la necesidad de .Espere, porque parece que siempre termina a tiempo. Existe el peligro de omitirlo si necesita completar la tarea antes de continuar. Por lo tanto, se debe usar .Wait, incluso si el 99% del tiempo, en realidad no se traduce en un tiempo de espera.

2

Una característica importante de Wait es que actúa como un punto de encuentro en el que cualquier excepción lanzada por el Task se volverá a tirar en este punto. Como la implementación actual de Task * le obliga a observar cualquier excepción de este tipo, Wait es una buena opción para hacerlo. Sin embargo, también puede observar la excepción al consultar la instancia Task para una excepción.

*) Al parecer, esto se cambiará. El comportamiento se cambia en el Async CTP.

Cuestiones relacionadas