WaitHandle.WaitAny Método
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Espera que qualquer um dos elementos do array especificado receba um sinal.
Sobrecargas
| Name | Description |
|---|---|
| WaitAny(WaitHandle[]) |
Espera que qualquer um dos elementos do array especificado receba um sinal. |
| WaitAny(WaitHandle[], Int32) |
Espera que qualquer um dos elementos do array especificado receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo. |
| WaitAny(WaitHandle[], TimeSpan) |
Espera que qualquer um dos elementos do array especificado receba um sinal, usando a TimeSpan para especificar o intervalo de tempo. |
| WaitAny(WaitHandle[], Int32, Boolean) |
Espera que qualquer um dos elementos do array especificado receba um sinal, usando um inteiro assinado de 32 bits para especificar o intervalo de tempo, e especificando se deve sair do domínio de sincronização antes da espera. |
| WaitAny(WaitHandle[], TimeSpan, Boolean) |
Espera que qualquer elemento do array especificado receba um sinal, usando a TimeSpan para especificar o intervalo de tempo e especificando se deve sair do domínio de sincronização antes da espera. |
WaitAny(WaitHandle[])
Espera que qualquer um dos elementos do array especificado receba um sinal.
public:
static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles);
static member WaitAny : System.Threading.WaitHandle[] -> int
Public Shared Function WaitAny (waitHandles As WaitHandle()) As Integer
Parâmetros
- waitHandles
- WaitHandle[]
Um WaitHandle array contendo os objetos para os quais a instância atual irá esperar.
Devoluções
O índice do array do objeto que satisfez a espera.
Exceções
O waitHandles parâmetro é null.
-ou-
Um ou mais dos objetos do waitHandles array é null.
O número de objetos em waitHandles é maior do que o sistema permite.
waitHandles é um array sem elementos, e a versão .NET Framework é 1.0 ou 1.1.
A espera terminou porque um tópico saiu sem divulgar um mutex.
waitHandles é um array sem elementos, e a versão .NET Framework é 2.0 ou posterior.
O waitHandles array contém um proxy transparente para um WaitHandle noutro domínio de aplicação.
Exemplos
O seguinte exemplo de código demonstra a chamada do WaitAny método.
using System;
using System.Threading;
public sealed class App
{
// Define an array with two AutoResetEvent WaitHandles.
static WaitHandle[] waitHandles = new WaitHandle[]
{
new AutoResetEvent(false),
new AutoResetEvent(false)
};
// Define a random number generator for testing.
static Random r = new Random();
static void Main()
{
// Queue up two tasks on two different threads;
// wait until all tasks are completed.
DateTime dt = DateTime.Now;
Console.WriteLine("Main thread is waiting for BOTH tasks to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
WaitHandle.WaitAll(waitHandles);
// The time shown below should match the longest task.
Console.WriteLine("Both tasks are completed (time waited={0})",
(DateTime.Now - dt).TotalMilliseconds);
// Queue up two tasks on two different threads;
// wait until any task is completed.
dt = DateTime.Now;
Console.WriteLine();
Console.WriteLine("The main thread is waiting for either task to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
int index = WaitHandle.WaitAny(waitHandles);
// The time shown below should match the shortest task.
Console.WriteLine("Task {0} finished first (time waited={1}).",
index + 1, (DateTime.Now - dt).TotalMilliseconds);
}
static void DoTask(Object state)
{
AutoResetEvent are = (AutoResetEvent) state;
int time = 1000 * r.Next(2, 10);
Console.WriteLine("Performing a task for {0} milliseconds.", time);
Thread.Sleep(time);
are.Set();
}
}
// This code produces output similar to the following:
//
// Main thread is waiting for BOTH tasks to complete.
// Performing a task for 7000 milliseconds.
// Performing a task for 4000 milliseconds.
// Both tasks are completed (time waited=7064.8052)
//
// The main thread is waiting for either task to complete.
// Performing a task for 2000 milliseconds.
// Performing a task for 2000 milliseconds.
// Task 1 finished first (time waited=2000.6528).
Imports System.Threading
NotInheritable Public Class App
' Define an array with two AutoResetEvent WaitHandles.
Private Shared waitHandles() As WaitHandle = _
{New AutoResetEvent(False), New AutoResetEvent(False)}
' Define a random number generator for testing.
Private Shared r As New Random()
<MTAThreadAttribute> _
Public Shared Sub Main()
' Queue two tasks on two different threads;
' wait until all tasks are completed.
Dim dt As DateTime = DateTime.Now
Console.WriteLine("Main thread is waiting for BOTH tasks to complete.")
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
WaitHandle.WaitAll(waitHandles)
' The time shown below should match the longest task.
Console.WriteLine("Both tasks are completed (time waited={0})", _
(DateTime.Now - dt).TotalMilliseconds)
' Queue up two tasks on two different threads;
' wait until any tasks are completed.
dt = DateTime.Now
Console.WriteLine()
Console.WriteLine("The main thread is waiting for either task to complete.")
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(0))
ThreadPool.QueueUserWorkItem(AddressOf DoTask, waitHandles(1))
Dim index As Integer = WaitHandle.WaitAny(waitHandles)
' The time shown below should match the shortest task.
Console.WriteLine("Task {0} finished first (time waited={1}).", _
index + 1,(DateTime.Now - dt).TotalMilliseconds)
End Sub
Shared Sub DoTask(ByVal state As [Object])
Dim are As AutoResetEvent = CType(state, AutoResetEvent)
Dim time As Integer = 1000 * r.Next(2, 10)
Console.WriteLine("Performing a task for {0} milliseconds.", time)
Thread.Sleep(time)
are.Set()
End Sub
End Class
' This code produces output similar to the following:
'
' Main thread is waiting for BOTH tasks to complete.
' Performing a task for 7000 milliseconds.
' Performing a task for 4000 milliseconds.
' Both tasks are completed (time waited=7064.8052)
'
' The main thread is waiting for either task to complete.
' Performing a task for 2000 milliseconds.
' Performing a task for 2000 milliseconds.
' Task 1 finished first (time waited=2000.6528).
Observações
AbandonedMutexException é novo na versão 2.0 do .NET Framework. Em versões anteriores, o WaitAny método retorna true se a espera for concluída porque um mutex é abandonado. Um mutex abandonado indica frequentemente um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que uma aplicação foi terminada abruptamente (por exemplo, usando o Gestor de Tarefas do Windows). A exceção contém informações úteis para depuração.
O WaitAny método lança uma AbandonedMutexException resposta apenas quando a espera termina devido a um mutex abandonado. Se waitHandles contiver um mutex libertado com um número de índice inferior ao mutex abandonado, o WaitAny método conclui normalmente e a exceção não é lançada.
Note
Nas versões do .NET Framework anteriores à versão 2.0, se uma thread sair ou abortar sem libertar explicitamente um Mutex, e Mutex estiver no índice 0 (zero) num array WaitAny noutra thread, o índice devolvido por WaitAny é 128 em vez de 0.
Este método retorna quando qualquer alavanca é sinalizada. Se mais do que um objeto for sinalizado durante a chamada, o valor de retorno é o índice do array do objeto sinalizado com o menor valor de índice de todos os objetos sinalizados.
O número máximo de handles de espera é 64, e 63 se o thread atual estiver em STA estado.
Chamar a este método overload é equivalente a chamar o WaitAny(WaitHandle[], Int32, Boolean) método overload e especificar -1 (ou Timeout.Infinite) para millisecondsTimeout e true para exitContext.
Aplica-se a
WaitAny(WaitHandle[], Int32)
Espera que qualquer um dos elementos do array especificado receba um sinal, usando um inteiro com sinal de 32 bits para especificar o intervalo de tempo.
public:
static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);
static member WaitAny : System.Threading.WaitHandle[] * int -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Integer
Parâmetros
- waitHandles
- WaitHandle[]
Um WaitHandle array contendo os objetos para os quais a instância atual irá esperar.
- millisecondsTimeout
- Int32
O número de milissegundos para esperar, ou Infinite (-1) para esperar indefinidamente.
Devoluções
O índice do array do objeto que satisfez a espera, ou WaitTimeout se nenhum objeto satisfez a espera e um intervalo de tempo equivalente a millisecondsTimeout já passou.
Exceções
O waitHandles parâmetro é null.
-ou-
Um ou mais dos objetos do waitHandles array é null.
O número de objetos em waitHandles é maior do que o sistema permite.
millisecondsTimeout é um número negativo diferente de -1, o que representa um tempo limite infinito.
A espera terminou porque um tópico saiu sem divulgar um mutex.
waitHandles é um array sem elementos.
O waitHandles array contém um proxy transparente para um WaitHandle noutro domínio de aplicação.
Observações
Se millisecondsTimeout for zero, o método não bloqueia. Testa o estado dos controlos de espera e retorna imediatamente.
O WaitAny método lança uma AbandonedMutexException resposta apenas quando a espera termina devido a um mutex abandonado. Se waitHandles contiver um mutex libertado com um número de índice inferior ao mutex abandonado, o WaitAny método conclui normalmente e a exceção não é lançada.
Este método retorna quando a espera termina, seja quando algum dos handles é sinalizado ou quando ocorre um timeout. Se mais do que um objeto for sinalizado durante a chamada, o valor de retorno é o índice do array do objeto sinalizado com o menor valor de índice de todos os objetos sinalizados.
O número máximo de handles de espera é 64, e 63 se o thread atual estiver em STA estado.
Chamar a este método overload é o mesmo que chamar a WaitAny(WaitHandle[], Int32, Boolean) overload e especificar false para exitContext.
Aplica-se a
WaitAny(WaitHandle[], TimeSpan)
Espera que qualquer um dos elementos do array especificado receba um sinal, usando a TimeSpan para especificar o intervalo de tempo.
public:
static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);
static member WaitAny : System.Threading.WaitHandle[] * TimeSpan -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), timeout As TimeSpan) As Integer
Parâmetros
- waitHandles
- WaitHandle[]
Um WaitHandle array contendo os objetos para os quais a instância atual irá esperar.
- timeout
- TimeSpan
A TimeSpan que representa o número de milissegundos para esperar, ou a TimeSpan que representa -1 milissegundos para esperar indefinidamente.
Devoluções
O índice do array do objeto que satisfez a espera, ou WaitTimeout se nenhum objeto satisfez a espera e um intervalo de tempo equivalente a timeout já passou.
Exceções
O waitHandles parâmetro é null.
-ou-
Um ou mais dos objetos do waitHandles array é null.
O número de objetos em waitHandles é maior do que o sistema permite.
timeout é um número negativo diferente de -1 milissegundos, o que representa um tempo de espera infinito.
-ou-
timeout é maior do que Int32.MaxValue.
A espera terminou porque um tópico saiu sem divulgar um mutex.
waitHandles é um array sem elementos.
O waitHandles array contém um proxy transparente para um WaitHandle noutro domínio de aplicação.
Observações
Se timeout for zero, o método não bloqueia. Testa o estado dos controlos de espera e retorna imediatamente.
O WaitAny método lança uma AbandonedMutexException resposta apenas quando a espera termina devido a um mutex abandonado. Se waitHandles contiver um mutex libertado com um número de índice inferior ao mutex abandonado, o WaitAny método conclui normalmente e a exceção não é lançada.
Este método retorna quando a espera termina, seja quando alguma das alavancas é sinalizada ou quando ocorre um time-out. Se mais do que um objeto for sinalizado durante a chamada, o valor de retorno é o índice do array do objeto sinalizado com o menor valor de índice de todos os objetos sinalizados.
O número máximo de handles de espera é 64, e 63 se o thread atual estiver em STA estado.
O valor máximo para timeout é Int32.MaxValue.
Chamar a este método overload é o mesmo que chamar a WaitAny(WaitHandle[], TimeSpan, Boolean) overload e especificar false para exitContext.
Aplica-se a
WaitAny(WaitHandle[], Int32, Boolean)
Espera que qualquer um dos elementos do array especificado receba um sinal, usando um inteiro assinado de 32 bits para especificar o intervalo de tempo, e especificando se deve sair do domínio de sincronização antes da espera.
public:
static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout, bool exitContext);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);
static member WaitAny : System.Threading.WaitHandle[] * int * bool -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Integer
Parâmetros
- waitHandles
- WaitHandle[]
Um WaitHandle array contendo os objetos para os quais a instância atual irá esperar.
- millisecondsTimeout
- Int32
O número de milissegundos para esperar, ou Infinite (-1) para esperar indefinidamente.
- exitContext
- Boolean
true sair do domínio de sincronização do contexto antes da espera (se estiver num contexto sincronizado), e readquiri-lo depois; caso contrário, false.
Devoluções
O índice do array do objeto que satisfez a espera, ou WaitTimeout se nenhum objeto satisfez a espera e um intervalo de tempo equivalente a millisecondsTimeout já passou.
Exceções
O waitHandles parâmetro é null.
-ou-
Um ou mais dos objetos do waitHandles array é null.
O número de objetos em waitHandles é maior do que o sistema permite.
waitHandles é um array sem elementos, e a versão .NET Framework é 1.0 ou 1.1.
millisecondsTimeout é um número negativo diferente de -1, o que representa um tempo limite infinito.
A espera terminou porque um tópico saiu sem divulgar um mutex.
waitHandles é um array sem elementos, e a versão .NET Framework é 2.0 ou posterior.
O waitHandles array contém um proxy transparente para um WaitHandle noutro domínio de aplicação.
Exemplos
O exemplo de código seguinte demonstra como usar o pool de threads para procurar simultaneamente um ficheiro em múltiplos discos. Para considerações de espaço, apenas se pesquisa o diretório raiz de cada disco.
using System;
using System.IO;
using System.Threading;
class Test
{
static void Main()
{
Search search = new Search();
search.FindFile("SomeFile.dat");
}
}
class Search
{
// Maintain state information to pass to FindCallback.
class State
{
public AutoResetEvent autoEvent;
public string fileName;
public State(AutoResetEvent autoEvent, string fileName)
{
this.autoEvent = autoEvent;
this.fileName = fileName;
}
}
AutoResetEvent[] autoEvents;
String[] diskLetters;
public Search()
{
// Retrieve an array of disk letters.
diskLetters = Environment.GetLogicalDrives();
autoEvents = new AutoResetEvent[diskLetters.Length];
for(int i = 0; i < diskLetters.Length; i++)
{
autoEvents[i] = new AutoResetEvent(false);
}
}
// Search for fileName in the root directory of all disks.
public void FindFile(string fileName)
{
for(int i = 0; i < diskLetters.Length; i++)
{
Console.WriteLine("Searching for {0} on {1}.",
fileName, diskLetters[i]);
ThreadPool.QueueUserWorkItem(
new WaitCallback(FindCallback),
new State(autoEvents[i], diskLetters[i] + fileName));
}
// Wait for the first instance of the file to be found.
int index = WaitHandle.WaitAny(autoEvents, 3000, false);
if(index == WaitHandle.WaitTimeout)
{
Console.WriteLine("\n{0} not found.", fileName);
}
else
{
Console.WriteLine("\n{0} found on {1}.", fileName,
diskLetters[index]);
}
}
// Search for stateInfo.fileName.
void FindCallback(object state)
{
State stateInfo = (State)state;
// Signal if the file is found.
if(File.Exists(stateInfo.fileName))
{
stateInfo.autoEvent.Set();
}
}
}
Imports System.IO
Imports System.Threading
Public Class Test
<MTAThread> _
Shared Sub Main()
Dim search As New Search()
search.FindFile("SomeFile.dat")
End Sub
End Class
Public Class Search
' Maintain state information to pass to FindCallback.
Class State
Public autoEvent As AutoResetEvent
Public fileName As String
Sub New(anEvent As AutoResetEvent, fName As String)
autoEvent = anEvent
fileName = fName
End Sub
End Class
Dim autoEvents() As AutoResetEvent
Dim diskLetters() As String
Sub New()
' Retrieve an array of disk letters.
diskLetters = Environment.GetLogicalDrives()
autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
For i As Integer = 0 To diskLetters.Length - 1
autoEvents(i) = New AutoResetEvent(False)
Next i
End Sub
' Search for fileName in the root directory of all disks.
Sub FindFile(fileName As String)
For i As Integer = 0 To diskLetters.Length - 1
Console.WriteLine("Searching for {0} on {1}.", _
fileName, diskLetters(i))
ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _
New State(autoEvents(i), diskLetters(i) & fileName))
Next i
' Wait for the first instance of the file to be found.
Dim index As Integer = _
WaitHandle.WaitAny(autoEvents, 3000, False)
If index = WaitHandle.WaitTimeout
Console.WriteLine(vbCrLf & "{0} not found.", fileName)
Else
Console.WriteLine(vbCrLf & "{0} found on {1}.", _
fileName, diskLetters(index))
End If
End Sub
' Search for stateInfo.fileName.
Sub FindCallback(state As Object)
Dim stateInfo As State = DirectCast(state, State)
' Signal if the file is found.
If File.Exists(stateInfo.fileName) Then
stateInfo.autoEvent.Set()
End If
End Sub
End Class
Observações
Se millisecondsTimeout for zero, o método não bloqueia. Testa o estado dos controlos de espera e retorna imediatamente.
O WaitAny método lança uma AbandonedMutexException resposta apenas quando a espera termina devido a um mutex abandonado. Se waitHandles contiver um mutex libertado com um número de índice inferior ao mutex abandonado, o WaitAny método conclui normalmente e a exceção não é lançada. Um mutex abandonado indica frequentemente um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que uma aplicação foi terminada abruptamente (por exemplo, usando o Gestor de Tarefas do Windows). A exceção contém informações úteis para depuração.
Este método retorna quando a espera termina, seja quando algum dos handles é sinalizado ou quando ocorre um timeout. Se mais do que um objeto for sinalizado durante a chamada, o valor de retorno é o índice do array do objeto sinalizado com o menor valor de índice de todos os objetos sinalizados.
O número máximo de handles de espera é 64, e 63 se o thread atual estiver em STA estado.
Saindo do contexto
O exitContext parâmetro não tem efeito a menos que este método seja chamado dentro de um contexto gerido não predefinido. O contexto gerido pode ser não padrão se o seu thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que esteja atualmente a executar um método numa classe que não deriva de ContextBoundObject, como String, pode estar num contexto não padrão se a ContextBoundObject estiver na sua pilha no domínio de aplicação atual.
Quando o seu código está a ser executado num contexto não padrão, especificar true para exitContext faz com que o thread saia do contexto gerido não padrão (isto é, para transitar para o contexto padrão) antes de executar este método. O thread regressa ao contexto original não padrão após a conclusão da chamada a este método.
Sair do contexto pode ser útil quando a classe ligada ao contexto tem o SynchronizationAttribute atributo. Nesse caso, todas as chamadas para membros da classe são sincronizadas automaticamente e o domínio de sincronização é todo o corpo de código da classe. Se o código na pilha de chamadas de um membro chamar este método e especificar true para exitContext, o thread sai do domínio de sincronização, o que permite que um thread bloqueado numa chamada para qualquer membro do objeto prossiga. Quando este método regressa, o thread que fez a chamada tem de esperar para reentrar no domínio de sincronização.
Aplica-se a
WaitAny(WaitHandle[], TimeSpan, Boolean)
Espera que qualquer elemento do array especificado receba um sinal, usando a TimeSpan para especificar o intervalo de tempo e especificando se deve sair do domínio de sincronização antes da espera.
public:
static int WaitAny(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout, bool exitContext);
public static int WaitAny(System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);
static member WaitAny : System.Threading.WaitHandle[] * TimeSpan * bool -> int
Public Shared Function WaitAny (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Integer
Parâmetros
- waitHandles
- WaitHandle[]
Um WaitHandle array contendo os objetos para os quais a instância atual irá esperar.
- timeout
- TimeSpan
A TimeSpan que representa o número de milissegundos para esperar, ou a TimeSpan que representa -1 milissegundos para esperar indefinidamente.
- exitContext
- Boolean
true sair do domínio de sincronização do contexto antes da espera (se estiver num contexto sincronizado), e readquiri-lo depois; caso contrário, false.
Devoluções
O índice do array do objeto que satisfez a espera, ou WaitTimeout se nenhum objeto satisfez a espera e um intervalo de tempo equivalente a timeout já passou.
Exceções
O waitHandles parâmetro é null.
-ou-
Um ou mais dos objetos do waitHandles array é null.
O número de objetos em waitHandles é maior do que o sistema permite.
waitHandles é um array sem elementos, e a versão .NET Framework é 1.0 ou 1.1.
timeout é um número negativo diferente de -1 milissegundos, o que representa um tempo de espera infinito.
-ou-
timeout é maior do que Int32.MaxValue.
A espera terminou porque um tópico saiu sem divulgar um mutex.
waitHandles é um array sem elementos, e a versão .NET Framework é 2.0 ou posterior.
O waitHandles array contém um proxy transparente para um WaitHandle noutro domínio de aplicação.
Exemplos
O exemplo de código seguinte demonstra como usar o pool de threads para procurar simultaneamente um ficheiro em múltiplos discos. Para considerações de espaço, apenas se pesquisa o diretório raiz de cada disco.
using System;
using System.IO;
using System.Threading;
class Test
{
static void Main()
{
Search search = new Search();
search.FindFile("SomeFile.dat");
}
}
class Search
{
// Maintain state information to pass to FindCallback.
class State
{
public AutoResetEvent autoEvent;
public string fileName;
public State(AutoResetEvent autoEvent, string fileName)
{
this.autoEvent = autoEvent;
this.fileName = fileName;
}
}
AutoResetEvent[] autoEvents;
String[] diskLetters;
public Search()
{
// Retrieve an array of disk letters.
diskLetters = Environment.GetLogicalDrives();
autoEvents = new AutoResetEvent[diskLetters.Length];
for(int i = 0; i < diskLetters.Length; i++)
{
autoEvents[i] = new AutoResetEvent(false);
}
}
// Search for fileName in the root directory of all disks.
public void FindFile(string fileName)
{
for(int i = 0; i < diskLetters.Length; i++)
{
Console.WriteLine("Searching for {0} on {1}.",
fileName, diskLetters[i]);
ThreadPool.QueueUserWorkItem(
new WaitCallback(FindCallback),
new State(autoEvents[i], diskLetters[i] + fileName));
}
// Wait for the first instance of the file to be found.
int index = WaitHandle.WaitAny(
autoEvents, new TimeSpan(0, 0, 3), false);
if(index == WaitHandle.WaitTimeout)
{
Console.WriteLine("\n{0} not found.", fileName);
}
else
{
Console.WriteLine("\n{0} found on {1}.", fileName,
diskLetters[index]);
}
}
// Search for stateInfo.fileName.
void FindCallback(object state)
{
State stateInfo = (State)state;
// Signal if the file is found.
if(File.Exists(stateInfo.fileName))
{
stateInfo.autoEvent.Set();
}
}
}
Imports System.IO
Imports System.Threading
Public Class Test
<MTAThread> _
Shared Sub Main()
Dim search As New Search()
search.FindFile("SomeFile.dat")
End Sub
End Class
Public Class Search
' Maintain state information to pass to FindCallback.
Class State
Public autoEvent As AutoResetEvent
Public fileName As String
Sub New(anEvent As AutoResetEvent, fName As String)
autoEvent = anEvent
fileName = fName
End Sub
End Class
Dim autoEvents() As AutoResetEvent
Dim diskLetters() As String
Sub New()
' Retrieve an array of disk letters.
diskLetters = Environment.GetLogicalDrives()
autoEvents = New AutoResetEvent(diskLetters.Length - 1) {}
For i As Integer = 0 To diskLetters.Length - 1
autoEvents(i) = New AutoResetEvent(False)
Next i
End Sub
' Search for fileName in the root directory of all disks.
Sub FindFile(fileName As String)
For i As Integer = 0 To diskLetters.Length - 1
Console.WriteLine("Searching for {0} on {1}.", _
fileName, diskLetters(i))
ThreadPool.QueueUserWorkItem(AddressOf FindCallback, _
New State(autoEvents(i), diskLetters(i) & fileName))
Next i
' Wait for the first instance of the file to be found.
Dim index As Integer = WaitHandle.WaitAny( _
autoEvents, New TimeSpan(0, 0, 3), False)
If index = WaitHandle.WaitTimeout
Console.WriteLine(vbCrLf & "{0} not found.", fileName)
Else
Console.WriteLine(vbCrLf & "{0} found on {1}.", _
fileName, diskLetters(index))
End If
End Sub
' Search for stateInfo.fileName.
Sub FindCallback(state As Object)
Dim stateInfo As State = DirectCast(state, State)
' Signal if the file is found.
If File.Exists(stateInfo.fileName) Then
stateInfo.autoEvent.Set()
End If
End Sub
End Class
Observações
Se timeout for zero, o método não bloqueia. Testa o estado dos controlos de espera e retorna imediatamente.
O WaitAny método lança uma AbandonedMutexException resposta apenas quando a espera termina devido a um mutex abandonado. Se waitHandles contiver um mutex libertado com um número de índice inferior ao mutex abandonado, o WaitAny método conclui normalmente e a exceção não é lançada. Um mutex abandonado indica frequentemente um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que uma aplicação foi terminada abruptamente (por exemplo, usando o Gestor de Tarefas do Windows). A exceção contém informações úteis para depuração.
Este método retorna quando a espera termina, seja quando alguma das alavancas é sinalizada ou quando ocorre um time-out. Se mais do que um objeto for sinalizado durante a chamada, o valor de retorno é o índice do array do objeto sinalizado com o menor valor de índice de todos os objetos sinalizados.
O número máximo de handles de espera é 64, e 63 se o thread atual estiver em STA estado.
O valor máximo para timeout é Int32.MaxValue.
Saindo do contexto
O exitContext parâmetro não tem efeito a menos que este método seja chamado dentro de um contexto gerido não predefinido. O contexto gerido pode ser não padrão se o seu thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que esteja atualmente a executar um método numa classe que não deriva de ContextBoundObject, como String, pode estar num contexto não padrão se a ContextBoundObject estiver na sua pilha no domínio de aplicação atual.
Quando o seu código está a ser executado num contexto não padrão, especificar true para exitContext faz com que o thread saia do contexto gerido não padrão (isto é, para transitar para o contexto padrão) antes de executar este método. O thread regressa ao contexto original não padrão após a conclusão da chamada a este método.
Sair do contexto pode ser útil quando a classe ligada ao contexto tem o SynchronizationAttribute atributo. Nesse caso, todas as chamadas para membros da classe são sincronizadas automaticamente e o domínio de sincronização é todo o corpo de código da classe. Se o código na pilha de chamadas de um membro chamar este método e especificar true para exitContext, o thread sai do domínio de sincronização, o que permite que um thread bloqueado numa chamada para qualquer membro do objeto prossiga. Quando este método regressa, o thread que fez a chamada tem de esperar para reentrar no domínio de sincronização.