Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este ejemplo se muestra cómo utilizar el método Wait o su equivalente en la clase Task<TResult>, para esperar en una tarea única. También se muestra cómo utilizar los métodos WaitAny y WaitAll estáticos para esperar en varias tareas.
Ejemplo
' How to: Wait on One or More Tasks to Complete
Imports System.Threading
Imports System.Threading.Tasks
Module WaitOnTasks
Dim rand As New Random()
Sub Main()
' Wait on a single task with no timeout specified.
Dim taskA = Task.Factory.StartNew(Sub() DoSomeWork(10000000))
taskA.Wait()
Console.WriteLine("taskA has completed.")
' Wait on a single task with a timeout specified.
Dim taskB = Task.Factory.StartNew(Sub() DoSomeWork(10000000))
taskB.Wait(100) 'Wait for 100 ms.
If (taskB.IsCompleted) Then
Console.WriteLine("taskB has completed.")
Else
Console.WriteLine("Timed out before task2 completed.")
End If
' Wait for all tasks to complete.
Dim myTasks(9) As Task
For i As Integer = 0 To myTasks.Length - 1
myTasks(i) = Task.Factory.StartNew(Sub() DoSomeWork(10000000))
Next
Task.WaitAll(myTasks)
' Wait for first task to complete.
Dim tasks2(2) As Task(Of Double)
' Try three different approaches to the problem. Take the first one.
tasks2(0) = Task(Of Double).Factory.StartNew(Function() TrySolution1())
tasks2(1) = Task(Of Double).Factory.StartNew(Function() TrySolution2())
tasks2(2) = Task(Of Double).Factory.StartNew(Function() TrySolution3())
Dim index As Integer = Task.WaitAny(tasks2)
Dim d As Double = tasks2(index).Result
Console.WriteLine("task(0) completed first with result of {1}.", index, d)
Console.ReadKey()
End Sub
' Dummy Functions to Simulate Work
Function DoSomeWork(ByVal val As Integer)
' Pretend to do something.
Thread.SpinWait(val)
End Function
Function TrySolution1()
Dim i As Integer = rand.Next(1000000)
' Simulate work by spinning
Thread.SpinWait(i)
Return i
End Function
Function TrySolution2()
Dim i As Integer = rand.Next(1000000)
' Simulate work by spinning
Thread.SpinWait(i)
Return i
End Function
Function TrySolution3()
Dim i As Integer = rand.Next(1000000)
' Simulate work by spinning
Thread.SpinWait(i)
Thread.SpinWait(1000000)
Return i
End Function
End Module
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static Random rand = new Random();
static void Main(string[] args)
{
// Wait on a single task with no timeout specified.
Task taskA = Task.Factory.StartNew(() => DoSomeWork(10000000));
taskA.Wait();
Console.WriteLine("taskA has completed.");
// Wait on a single task with a timeout specified.
Task taskB = Task.Factory.StartNew(() => DoSomeWork(10000000));
taskB.Wait(100); //Wait for 100 ms.
if (taskB.IsCompleted)
Console.WriteLine("taskB has completed.");
else
Console.WriteLine("Timed out before taskB completed.");
// Wait for all tasks to complete.
Task[] tasks = new Task[10];
for (int i = 0; i < 10; i++)
{
tasks[i] = Task.Factory.StartNew(() => DoSomeWork(10000000));
}
Task.WaitAll(tasks);
// Wait for first task to complete.
Task<double>[] tasks2 = new Task<double>[3];
// Try three different approaches to the problem. Take the first one.
tasks2[0] = Task<double>.Factory.StartNew(() => TrySolution1());
tasks2[1] = Task<double>.Factory.StartNew(() => TrySolution2());
tasks2[2] = Task<double>.Factory.StartNew(() => TrySolution3());
int index = Task.WaitAny(tasks2);
double d = tasks2[index].Result;
Console.WriteLine("task[{0}] completed first with result of {1}.", index, d);
Console.ReadKey();
}
static void DoSomeWork(int val)
{
// Pretend to do something.
Thread.SpinWait(val);
}
static double TrySolution1()
{
int i = rand.Next(1000000);
// Simulate work by spinning
Thread.SpinWait(i);
return DateTime.Now.Millisecond;
}
static double TrySolution2()
{
int i = rand.Next(1000000);
// Simulate work by spinning
Thread.SpinWait(i);
return DateTime.Now.Millisecond;
}
static double TrySolution3()
{
int i = rand.Next(1000000);
// Simulate work by spinning
Thread.SpinWait(i);
Thread.SpinWait(1000000);
return DateTime.Now.Millisecond;
}
}
Por razones de simplicidad, estos ejemplos no muestran el código de control de excepciones ni el código de cancelación. En la mayoría de los casos, debe incluir un método Wait en un bloque try-catch, porque la espera es el mecanismo por el que el código de programa controla las excepciones que se inician en cualquiera de las tareas. Para obtener más información, vea Cómo: Controlar excepciones iniciadas por tareas. Si la tarea se puede cancelar, debe comprobar las propiedades IsCanceled o IsCancellationRequested() antes de intentar utilizar la tarea o su propiedad Result(). Para obtener más información, vea Cómo: Cancelar una tarea y sus elementos secundarios.
Vea también
Conceptos
Expresiones lambda en PLINQ y TPL