Como: Espera-se em uma ou mais tarefas para concluir
Este exemplo mostra como usar o Wait método ou seu equivalente na Task<TResult> classe, para aguardar uma única tarefa. Ele também mostra como usar estática WaitAll e WaitAny métodos de espera em várias tarefas.
Exemplo
' 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;
}
}
Para fins de simplicidade, esses exemplos não mostram o código ou o código de cancelamento de manipulação de exceção. Na maioria dos casos, você deve colocar um Wait método em um try-catch bloquear porque espera é o mecanismo pelo qual o código de programa manipula as exceções que são geradas a partir de qualquer uma das tarefas. Para obter mais informações, consulte Como: Manipular exceções lançadas por tarefas. Se sua tarefa é cancelável, você deve verificar a IsCanceled ou IsCancellationRequested() propriedade antes de consumir a tarefa ou de sua Result() propriedade. Para obter mais informações, consulte Como: Cancelar uma tarefa e seus filhos.
Consulte também
Conceitos
Expressões lambda no PLINQ e TPL