Recibes ese error porque la Task
clase ya inició la tarea antes de dártela. Solo debe llamar Start
a una tarea que crea llamando a su constructor, y ni siquiera debe hacerlo a menos que tenga una razón convincente para no iniciar la tarea cuando la cree; si desea que comience de inmediato, debe usar Task.Run
o Task.Factory.StartNew
para crear y comenzar uno nuevo Task
.
Entonces, ahora sabemos simplemente deshacernos de ese molesto Start
. Ejecutará su código y encontrará que el cuadro de mensaje se muestra de inmediato, no 5 segundos después, ¿qué pasa con eso?
Bueno, Task.Delay
solo te da una tarea que se completará en 5 segundos. No detiene la ejecución del hilo durante 5 segundos. Lo que quiere hacer es tener un código que se ejecute después de que finalice la tarea. Para eso ContinueWith
es. Le permite ejecutar algún código después de que se realiza una tarea determinada:
public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}
Esto se comportará como se esperaba.
También podríamos aprovechar la await
palabra clave de C # 5.0 para agregar continuaciones más fácilmente:
public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}
Si bien una explicación completa de lo que está sucediendo aquí está más allá del alcance de esta pregunta, el resultado final es un método que se comporta de manera muy similar al método anterior; mostrará un cuadro de mensaje 5 segundos después de llamar al método, pero el método en sí regresará [casi] inmediatamente en ambos casos. Dicho esto, await
es muy poderoso y nos permite escribir métodos que parecen simples y directos, pero que serían mucho más difíciles y complicados de escribir usando ContinueWith
directamente. También simplifica enormemente el manejo de errores, eliminando una gran cantidad de código repetitivo.
Wait()
a una tarea bloqueará el hilo actual hasta que la tarea se resuelva. Eso casi nunca es lo que quieres que suceda.