WaitHandle.WaitAll Método
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Aguarda até que todos os elementos na matriz especificada recebam um sinal.
Sobrecargas
WaitAll(WaitHandle[], TimeSpan, Boolean) |
Aguarda até que todos os elementos da matriz especificada recebam um sinal, usando um valor TimeSpan para especificar o intervalo de tempo e especificando se sairá do domínio de sincronização antes da espera. |
WaitAll(WaitHandle[], Int32, Boolean) |
Espera todos os elementos da matriz especificada receberem um sinal, usando um valor Int32 para especificar o intervalo de tempo e especificar se deseja sair do domínio de sincronização antes do tempo de espera. |
WaitAll(WaitHandle[], TimeSpan) |
Espera que todos os elementos na matriz especificada recebam um sinal usando um valor TimeSpan para especificar o intervalo de tempo. |
WaitAll(WaitHandle[], Int32) |
Espera que todos os elementos na matriz especificada recebam um sinal usando um valor Int32 para especificar o intervalo de tempo. |
WaitAll(WaitHandle[]) |
Aguarda até que todos os elementos na matriz especificada recebam um sinal. |
WaitAll(WaitHandle[], TimeSpan, Boolean)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Aguarda até que todos os elementos da matriz especificada recebam um sinal, usando um valor TimeSpan para especificar o intervalo de tempo e especificando se sairá do domínio de sincronização antes da espera.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout, bool exitContext);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);
static member WaitAll : System.Threading.WaitHandle[] * TimeSpan * bool -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan, exitContext As Boolean) As Boolean
Parâmetros
- waitHandles
- WaitHandle[]
Uma matriz WaitHandle
que contém os objetos que a instância atual aguardará. Essa matriz não pode conter várias referências ao mesmo objeto.
- timeout
- TimeSpan
Um TimeSpan que representa o número de milissegundos para aguardar ou um TimeSpan que representa -1 milissegundos para aguardar indefinidamente.
- exitContext
- Boolean
true
para sair do domínio de sincronização do contexto antes do tempo de espera (se estiver em um contexto sincronizado) e readquiri-lo posteriormente; caso contrário, false
.
Retornos
true
quando todos os elementos em waitHandles
tiverem recebido um sinal; caso contrário, false
.
Exceções
O parâmetro waitHandles
é null
.
- ou -
Um ou mais dos objetos na matriz waitHandles
é null
.
- ou -
waitHandles
é uma matriz sem elementos e a versão do .NET Framework é 2.0 ou posterior.
A matriz waitHandles
contém elementos duplicados.
O número de objetos em waitHandles
é maior do que o sistema permite.
- ou -
O atributo STAThreadAttribute é aplicado ao procedimento de thread para o thread atual e waitHandles
contém mais de um elemento.
waitHandles
é uma matriz sem elementos e a versão do .NET Framework é 1.0 ou 1.1.
timeout
é um número negativo diferente de -1 milissegundo, que representa um tempo limite infinito.
- ou -
timeout
é maior que Int32.MaxValue.
A espera terminou porque um thread foi encerrado sem liberar um mutex.
A matriz waitHandles
contendo um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Exemplos
O exemplo de código a seguir mostra como usar o pool de threads para criar e gravar de forma assíncrona em um grupo de arquivos. Cada operação de gravação é enfileirada como um item de trabalho e sinaliza quando é concluída. O thread principal aguarda que todos os itens sinalizem e saiam.
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
// Maintain state to pass to WriteToFile.
ref class State
{
public:
String^ fileName;
array<Byte>^byteArray;
ManualResetEvent^ manualEvent;
State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
: fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
{}
};
ref class Writer
{
private:
static int workItemCount = 0;
Writer(){}
public:
static void WriteToFile( Object^ state )
{
int workItemNumber = workItemCount;
Interlocked::Increment( workItemCount );
Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
State^ stateInfo = dynamic_cast<State^>(state);
FileStream^ fileWriter;
// Create and write to the file.
try
{
fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
}
finally
{
if ( fileWriter != nullptr )
{
fileWriter->Close();
}
// Signal main() that the work item has finished.
Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
stateInfo->manualEvent->Set();
}
}
};
int main()
{
const int numberOfFiles = 5;
String^ dirName = "C:\\TestTest";
String^ fileName;
array<Byte>^byteArray;
Random^ randomGenerator = gcnew Random;
array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
State^ stateInfo;
if ( !Directory::Exists( dirName ) )
{
Directory::CreateDirectory( dirName );
}
// Queue the work items that create and write to the files.
for ( int i = 0; i < numberOfFiles; i++ )
{
fileName = String::Concat( dirName, "\\Test", ((i)).ToString(), ".dat" );
// Create random data to write to the file.
byteArray = gcnew array<Byte>(1000000);
randomGenerator->NextBytes( byteArray );
manualEvents[ i ] = gcnew ManualResetEvent( false );
stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
if ( WaitHandle::WaitAll( manualEvents, TimeSpan(0,0,5), false ) )
{
Console::WriteLine( "Files written - main exiting." );
}
else
{
// The wait operation times out.
Console::WriteLine( "Error writing files - main exiting." );
}
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;
class Test
{
static void Main()
{
const int numberOfFiles = 5;
string dirName = @"C:\TestTest";
string fileName;
byte[] byteArray;
Random randomGenerator = new Random();
ManualResetEvent[] manualEvents =
new ManualResetEvent[numberOfFiles];
State stateInfo;
if(!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
// Queue the work items that create and write to the files.
for(int i = 0; i < numberOfFiles; i++)
{
fileName = string.Concat(
dirName, @"\Test", i.ToString(), ".dat");
// Create random data to write to the file.
byteArray = new byte[1000000];
randomGenerator.NextBytes(byteArray);
manualEvents[i] = new ManualResetEvent(false);
stateInfo =
new State(fileName, byteArray, manualEvents[i]);
ThreadPool.QueueUserWorkItem(new WaitCallback(
Writer.WriteToFile), stateInfo);
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
if(WaitHandle.WaitAll(
manualEvents, new TimeSpan(0, 0, 5), false))
{
Console.WriteLine("Files written - main exiting.");
}
else
{
// The wait operation times out.
Console.WriteLine("Error writing files - main exiting.");
}
}
}
// Maintain state to pass to WriteToFile.
class State
{
public string fileName;
public byte[] byteArray;
public ManualResetEvent manualEvent;
public State(string fileName, byte[] byteArray,
ManualResetEvent manualEvent)
{
this.fileName = fileName;
this.byteArray = byteArray;
this.manualEvent = manualEvent;
}
}
class Writer
{
static int workItemCount = 0;
Writer() {}
public static void WriteToFile(object state)
{
int workItemNumber = workItemCount;
Interlocked.Increment(ref workItemCount);
Console.WriteLine("Starting work item {0}.",
workItemNumber.ToString());
State stateInfo = (State)state;
FileStream fileWriter = null;
// Create and write to the file.
try
{
fileWriter = new FileStream(
stateInfo.fileName, FileMode.Create);
fileWriter.Write(stateInfo.byteArray,
0, stateInfo.byteArray.Length);
}
finally
{
if(fileWriter != null)
{
fileWriter.Close();
}
// Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.",
workItemNumber.ToString());
stateInfo.manualEvent.Set();
}
}
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading
Public Class Test
' WaitHandle.WaitAll requires a multithreaded apartment
' when using multiple wait handles.
<MTAThreadAttribute> _
Shared Sub Main()
Const numberOfFiles As Integer = 5
Dim dirName As String = "C:\TestTest"
Dim fileName As String
Dim byteArray() As Byte
Dim randomGenerator As New Random()
Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
Dim stateInfo As State
If Directory.Exists(dirName) <> True Then
Directory.CreateDirectory(dirName)
End If
' Queue the work items that create and write to the files.
For i As Integer = 0 To numberOfFiles - 1
fileName = String.Concat( _
dirName, "\Test", i.ToString(), ".dat")
' Create random data to write to the file.
byteArray = New Byte(1000000){}
randomGenerator.NextBytes(byteArray)
manualEvents(i) = New ManualResetEvent(false)
stateInfo = _
New State(fileName, byteArray, manualEvents(i))
ThreadPool.QueueUserWorkItem(AddressOf _
Writer.WriteToFile, stateInfo)
Next i
' Since ThreadPool threads are background threads,
' wait for the work items to signal before exiting.
If WaitHandle.WaitAll( _
manualEvents, New TimeSpan(0, 0, 5), false) = True Then
Console.WriteLine("Files written - main exiting.")
Else
' The wait operation times out.
Console.WriteLine("Error writing files - main exiting.")
End If
End Sub
End Class
' Maintain state to pass to WriteToFile.
Public Class State
Public fileName As String
Public byteArray As Byte()
Public manualEvent As ManualResetEvent
Sub New(fileName As String, byteArray() As Byte, _
manualEvent As ManualResetEvent)
Me.fileName = fileName
Me.byteArray = byteArray
Me.manualEvent = manualEvent
End Sub
End Class
Public Class Writer
Private Sub New()
End Sub
Shared workItemCount As Integer = 0
Shared Sub WriteToFile(state As Object)
Dim workItemNumber As Integer = workItemCount
Interlocked.Increment(workItemCount)
Console.WriteLine("Starting work item {0}.", _
workItemNumber.ToString())
Dim stateInfo As State = CType(state, State)
Dim fileWriter As FileStream = Nothing
' Create and write to the file.
Try
fileWriter = New FileStream( _
stateInfo.fileName, FileMode.Create)
fileWriter.Write(stateInfo.byteArray, _
0, stateInfo.byteArray.Length)
Finally
If Not fileWriter Is Nothing Then
fileWriter.Close()
End If
' Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.", _
workItemNumber.ToString())
stateInfo.manualEvent.Set()
End Try
End Sub
End Class
Comentários
Se timeout
for zero, o método não bloqueará. Ele testa o estado dos identificadores de espera e retorna imediatamente.
Se um mutex for abandonado, um AbandonedMutexException será gerado. Um mutex abandonado geralmente indica um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.
O WaitAll método retorna quando a espera é encerrada, o que significa que todos os identificadores são sinalizados ou ocorre um tempo limite. Se mais de 64 identificadores forem passados, um NotSupportedException será gerado. Se a matriz contiver duplicatas, a chamada falhará.
O valor máximo para timeout
é Int32.MaxValue.
Saindo do contexto
O exitContext
parâmetro não tem efeito, a menos que esse método seja chamado de dentro de um contexto gerenciado não padrão. O contexto gerenciado poderá ser não padrão se o thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que você esteja executando um método em uma classe que não é derivada de ContextBoundObject, como String, você pode estar em um contexto não padrão se um ContextBoundObject estiver em sua pilha no domínio do aplicativo atual.
Quando o código está sendo executado em um contexto não padrão, especificar true
para exitContext
faz com que o thread saia do contexto gerenciado não padrão (ou seja, fazer a transição para o contexto padrão) antes de executar esse método. O thread retorna ao contexto não padrão original após a conclusão da chamada para esse método.
Sair do contexto pode ser útil quando a classe associada 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 do código para a classe . Se o código na pilha de chamadas de um membro chamar esse método e especificar true
para exitContext
, o thread sairá do domínio de sincronização, o que permitirá que um thread bloqueado em uma chamada para qualquer membro do objeto prossiga. Quando esse método retorna, o thread que fez a chamada deve aguardar para reentrada no domínio de sincronização.
Aplica-se a
WaitAll(WaitHandle[], Int32, Boolean)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Espera todos os elementos da matriz especificada receberem um sinal, usando um valor Int32 para especificar o intervalo de tempo e especificar se deseja sair do domínio de sincronização antes do tempo de espera.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout, bool exitContext);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);
static member WaitAll : System.Threading.WaitHandle[] * int * bool -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer, exitContext As Boolean) As Boolean
Parâmetros
- waitHandles
- WaitHandle[]
Uma matriz WaitHandle
que contém os objetos que a instância atual aguardará. Esta matriz não pode conter várias referências ao mesmo objeto (duplicações).
- millisecondsTimeout
- Int32
O número de milissegundos para aguardar ou Infinite (- 1) para aguardar indefinidamente.
- exitContext
- Boolean
true
para sair do domínio de sincronização do contexto antes do tempo de espera (se estiver em um contexto sincronizado) e readquiri-lo posteriormente; caso contrário, false
.
Retornos
true
quando todos os elementos em waitHandles
tiverem recebido um sinal; caso contrário, false
.
Exceções
O parâmetro waitHandles
é null
.
- ou -
Um ou mais dos objetos na matriz waitHandles
é null
.
- ou -
waitHandles
é uma matriz sem elementos e a versão do .NET Framework é 2.0 ou posterior.
A matriz waitHandles
contém elementos duplicados.
O número de objetos em waitHandles
é maior do que o sistema permite.
- ou -
O thread atual está no estado STA, e waitHandles
contém mais de um elemento.
waitHandles
é uma matriz sem elementos e a versão do .NET Framework é 1.0 ou 1.1.
millisecondsTimeout
é um número negativo diferente de -1, que representa um tempo limite infinito.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
A matriz waitHandles
contendo um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Exemplos
O exemplo de código a seguir mostra como usar o pool de threads para criar e gravar de forma assíncrona em um grupo de arquivos. Cada operação de gravação é enfileirada como um item de trabalho e sinaliza quando é concluída. O thread principal aguarda que todos os itens sinalizem e saiam.
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
// Maintain state to pass to WriteToFile.
ref class State
{
public:
String^ fileName;
array<Byte>^byteArray;
ManualResetEvent^ manualEvent;
State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
: fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
{}
};
ref class Writer
{
private:
static int workItemCount = 0;
Writer(){}
public:
static void WriteToFile( Object^ state )
{
int workItemNumber = workItemCount;
Interlocked::Increment( workItemCount );
Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
State^ stateInfo = dynamic_cast<State^>(state);
FileStream^ fileWriter;
// Create and write to the file.
try
{
fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
}
finally
{
if ( fileWriter != nullptr )
{
fileWriter->Close();
}
// Signal main() that the work item has finished.
Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
stateInfo->manualEvent->Set();
}
}
};
int main()
{
const int numberOfFiles = 5;
String^ dirName = "C:\\TestTest";
String^ fileName;
array<Byte>^byteArray;
Random^ randomGenerator = gcnew Random;
array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
State^ stateInfo;
if ( !Directory::Exists( dirName ) )
{
Directory::CreateDirectory( dirName );
}
// Queue the work items that create and write to the files.
for ( int i = 0; i < numberOfFiles; i++ )
{
fileName = String::Concat( dirName, "\\Test", ((i)).ToString(), ".dat" );
// Create random data to write to the file.
byteArray = gcnew array<Byte>(1000000);
randomGenerator->NextBytes( byteArray );
manualEvents[ i ] = gcnew ManualResetEvent( false );
stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
if ( WaitHandle::WaitAll( manualEvents, 5000, false ) )
{
Console::WriteLine( "Files written - main exiting." );
}
else
{
// The wait operation times out.
Console::WriteLine( "Error writing files - main exiting." );
}
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;
class Test
{
static void Main()
{
const int numberOfFiles = 5;
string dirName = @"C:\TestTest";
string fileName;
byte[] byteArray;
Random randomGenerator = new Random();
ManualResetEvent[] manualEvents =
new ManualResetEvent[numberOfFiles];
State stateInfo;
if(!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
// Queue the work items that create and write to the files.
for(int i = 0; i < numberOfFiles; i++)
{
fileName = string.Concat(
dirName, @"\Test", i.ToString(), ".dat");
// Create random data to write to the file.
byteArray = new byte[1000000];
randomGenerator.NextBytes(byteArray);
manualEvents[i] = new ManualResetEvent(false);
stateInfo =
new State(fileName, byteArray, manualEvents[i]);
ThreadPool.QueueUserWorkItem(new WaitCallback(
Writer.WriteToFile), stateInfo);
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
if(WaitHandle.WaitAll(manualEvents, 5000, false))
{
Console.WriteLine("Files written - main exiting.");
}
else
{
// The wait operation times out.
Console.WriteLine("Error writing files - main exiting.");
}
}
}
// Maintain state to pass to WriteToFile.
class State
{
public string fileName;
public byte[] byteArray;
public ManualResetEvent manualEvent;
public State(string fileName, byte[] byteArray,
ManualResetEvent manualEvent)
{
this.fileName = fileName;
this.byteArray = byteArray;
this.manualEvent = manualEvent;
}
}
class Writer
{
static int workItemCount = 0;
Writer() {}
public static void WriteToFile(object state)
{
int workItemNumber = workItemCount;
Interlocked.Increment(ref workItemCount);
Console.WriteLine("Starting work item {0}.",
workItemNumber.ToString());
State stateInfo = (State)state;
FileStream fileWriter = null;
// Create and write to the file.
try
{
fileWriter = new FileStream(
stateInfo.fileName, FileMode.Create);
fileWriter.Write(stateInfo.byteArray,
0, stateInfo.byteArray.Length);
}
finally
{
if(fileWriter != null)
{
fileWriter.Close();
}
// Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.",
workItemNumber.ToString());
stateInfo.manualEvent.Set();
}
}
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading
Public Class Test
' WaitHandle.WaitAll requires a multithreaded apartment
' when using multiple wait handles.
<MTAThreadAttribute> _
Shared Sub Main()
Const numberOfFiles As Integer = 5
Dim dirName As String = "C:\TestTest"
Dim fileName As String
Dim byteArray() As Byte
Dim randomGenerator As New Random()
Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
Dim stateInfo As State
If Directory.Exists(dirName) <> True Then
Directory.CreateDirectory(dirName)
End If
' Queue the work items that create and write to the files.
For i As Integer = 0 To numberOfFiles - 1
fileName = String.Concat( _
dirName, "\Test", i.ToString(), ".dat")
' Create random data to write to the file.
byteArray = New Byte(1000000){}
randomGenerator.NextBytes(byteArray)
manualEvents(i) = New ManualResetEvent(false)
stateInfo = _
New State(fileName, byteArray, manualEvents(i))
ThreadPool.QueueUserWorkItem(AddressOf _
Writer.WriteToFile, stateInfo)
Next i
' Since ThreadPool threads are background threads,
' wait for the work items to signal before exiting.
If WaitHandle.WaitAll(manualEvents, 5000, false) = True Then
Console.WriteLine("Files written - main exiting.")
Else
' The wait operation times out.
Console.WriteLine("Error writing files - main exiting.")
End If
End Sub
End Class
' Maintain state to pass to WriteToFile.
Public Class State
Public fileName As String
Public byteArray As Byte()
Public manualEvent As ManualResetEvent
Sub New(fileName As String, byteArray() As Byte, _
manualEvent As ManualResetEvent)
Me.fileName = fileName
Me.byteArray = byteArray
Me.manualEvent = manualEvent
End Sub
End Class
Public Class Writer
Private Sub New()
End Sub
Shared workItemCount As Integer = 0
Shared Sub WriteToFile(state As Object)
Dim workItemNumber As Integer = workItemCount
Interlocked.Increment(workItemCount)
Console.WriteLine("Starting work item {0}.", _
workItemNumber.ToString())
Dim stateInfo As State = CType(state, State)
Dim fileWriter As FileStream = Nothing
' Create and write to the file.
Try
fileWriter = New FileStream( _
stateInfo.fileName, FileMode.Create)
fileWriter.Write(stateInfo.byteArray, _
0, stateInfo.byteArray.Length)
Finally
If Not fileWriter Is Nothing Then
fileWriter.Close()
End If
' Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.", _
workItemNumber.ToString())
stateInfo.manualEvent.Set()
End Try
End Sub
End Class
Comentários
Se millisecondsTimeout
for zero, o método não bloqueará. Ele testa o estado dos identificadores de espera e retorna imediatamente.
Se um mutex for abandonado, um AbandonedMutexException será gerado. Um mutex abandonado geralmente indica um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.
O WaitAll método retorna quando a espera é encerrada, o que significa quando todos os identificadores são sinalizados ou quando ocorre um tempo limite. Se mais de 64 identificadores forem passados, um NotSupportedException será gerado. Se houver duplicatas na matriz, a chamada falhará com um DuplicateWaitObjectException.
Saindo do contexto
O exitContext
parâmetro não tem efeito, a menos que esse método seja chamado de dentro de um contexto gerenciado não padrão. O contexto gerenciado poderá ser não padrão se o thread estiver dentro de uma chamada para uma instância de uma classe derivada de ContextBoundObject. Mesmo que você esteja executando um método em uma classe que não é derivada de ContextBoundObject, como String, você pode estar em um contexto não padrão se um ContextBoundObject estiver em sua pilha no domínio do aplicativo atual.
Quando o código está sendo executado em um contexto não padrão, especificar true
para exitContext
faz com que o thread saia do contexto gerenciado não padrão (ou seja, fazer a transição para o contexto padrão) antes de executar esse método. O thread retorna ao contexto não padrão original após a conclusão da chamada para esse método.
Sair do contexto pode ser útil quando a classe associada 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 do código para a classe . Se o código na pilha de chamadas de um membro chamar esse método e especificar true
para exitContext
, o thread sairá do domínio de sincronização, o que permitirá que um thread bloqueado em uma chamada para qualquer membro do objeto prossiga. Quando esse método retorna, o thread que fez a chamada deve aguardar para reentrada no domínio de sincronização.
Aplica-se a
WaitAll(WaitHandle[], TimeSpan)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Espera que todos os elementos na matriz especificada recebam um sinal usando um valor TimeSpan para especificar o intervalo de tempo.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, TimeSpan timeout);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);
static member WaitAll : System.Threading.WaitHandle[] * TimeSpan -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), timeout As TimeSpan) As Boolean
Parâmetros
- waitHandles
- WaitHandle[]
Uma matriz WaitHandle
que contém os objetos que a instância atual aguardará. Essa matriz não pode conter várias referências ao mesmo objeto.
- timeout
- TimeSpan
Um TimeSpan que representa o número de milissegundos para aguardar ou um TimeSpan que representa -1 milissegundos para aguardar indefinidamente.
Retornos
true
quando todos os elementos em waitHandles
tiverem recebido um sinal; caso contrário, false
.
Exceções
O parâmetro waitHandles
é null
.
- ou -
Um ou mais dos objetos na matriz waitHandles
é null
.
- ou -
waitHandles
é uma matriz sem elementos.
A matriz waitHandles
contém elementos duplicados.
Observação: no .NET para aplicativos da Microsoft Store ou na Biblioteca de Classes Portátil, verifique a exceção de classe base, ArgumentException.
O número de objetos em waitHandles
é maior do que o sistema permite.
- ou -
O thread atual está no estado STA, e waitHandles
contém mais de um elemento.
timeout
é um número negativo diferente de -1 milissegundo, que representa um tempo limite infinito.
- ou -
timeout
é maior que Int32.MaxValue.
A espera terminou porque um thread foi encerrado sem liberar um mutex.
A matriz waitHandles
contendo um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Comentários
Se timeout
for zero, o método não bloqueará. Ele testa o estado dos identificadores de espera e retorna imediatamente.
O WaitAll método retorna quando a espera é encerrada, o que significa que todos os identificadores são sinalizados ou ocorre um tempo limite. Se mais de 64 identificadores forem passados, um NotSupportedException será gerado. Se a matriz contiver duplicatas, a chamada falhará.
O valor máximo para timeout
é Int32.MaxValue.
Chamar essa sobrecarga de método é o mesmo que chamar a WaitAll(WaitHandle[], TimeSpan, Boolean) sobrecarga e especificar false
para exitContext
.
Aplica-se a
WaitAll(WaitHandle[], Int32)
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Espera que todos os elementos na matriz especificada recebam um sinal usando um valor Int32 para especificar o intervalo de tempo.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles, int millisecondsTimeout);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);
static member WaitAll : System.Threading.WaitHandle[] * int -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle(), millisecondsTimeout As Integer) As Boolean
Parâmetros
- waitHandles
- WaitHandle[]
Uma matriz WaitHandle
que contém os objetos que a instância atual aguardará. Esta matriz não pode conter várias referências ao mesmo objeto (duplicações).
- millisecondsTimeout
- Int32
O número de milissegundos para aguardar ou Infinite (- 1) para aguardar indefinidamente.
Retornos
true
quando todos os elementos em waitHandles
tiverem recebido um sinal; caso contrário, false
.
Exceções
O parâmetro waitHandles
é null
.
- ou -
Um ou mais dos objetos na matriz waitHandles
é null
.
- ou -
waitHandles
é uma matriz sem elementos.
A matriz waitHandles
contém elementos duplicados.
Observação: no .NET para aplicativos da Microsoft Store ou na Biblioteca de Classes Portátil, verifique a exceção de classe base, ArgumentException.
O número de objetos em waitHandles
é maior do que o sistema permite.
- ou -
O thread atual está no estado STA, e waitHandles
contém mais de um elemento.
millisecondsTimeout
é um número negativo diferente de -1, que representa um tempo limite infinito.
A espera foi concluída porque um thread foi encerrado sem liberar um mutex.
A matriz waitHandles
contendo um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Comentários
Se millisecondsTimeout
for zero, o método não bloqueará. Ele testa o estado dos identificadores de espera e retorna imediatamente.
O WaitAll método retorna quando a espera é encerrada, o que significa quando todos os identificadores são sinalizados ou quando ocorre um tempo limite. Se mais de 64 identificadores forem passados, um NotSupportedException será gerado. Se houver duplicatas na matriz, a chamada falhará com um DuplicateWaitObjectException.
Chamar essa sobrecarga de método é o mesmo que chamar a WaitAll(WaitHandle[], Int32, Boolean) sobrecarga e especificar false
para exitContext
.
Aplica-se a
WaitAll(WaitHandle[])
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
- Origem:
- WaitHandle.cs
Aguarda até que todos os elementos na matriz especificada recebam um sinal.
public:
static bool WaitAll(cli::array <System::Threading::WaitHandle ^> ^ waitHandles);
public static bool WaitAll (System.Threading.WaitHandle[] waitHandles);
static member WaitAll : System.Threading.WaitHandle[] -> bool
Public Shared Function WaitAll (waitHandles As WaitHandle()) As Boolean
Parâmetros
- waitHandles
- WaitHandle[]
Uma matriz WaitHandle
que contém os objetos que a instância atual aguardará. Essa matriz não pode conter várias referências ao mesmo objeto.
Retornos
true
quando todos os elementos em waitHandles
tiverem recebido um sinal; caso contrário, o método nunca retornará.
Exceções
O parâmetro waitHandles
é null
. - ou -
Um ou mais dos objetos na matriz waitHandles
são null
.
- ou -
waitHandles
é uma matriz sem elementos e a versão do .NET Framework é 2.0 ou posterior.
A matriz waitHandles
contém elementos duplicados.
Observação: no .NET para aplicativos da Microsoft Store ou na Biblioteca de Classes Portátil, verifique a exceção de classe base, ArgumentException.
O número de objetos em waitHandles
é maior do que o sistema permite.
- ou -
O thread atual está no estado STA, e waitHandles
contém mais de um elemento.
waitHandles
é uma matriz sem elementos e a versão do .NET Framework é 1.0 ou 1.1.
A espera terminou porque um thread foi encerrado sem liberar um mutex.
A matriz waitHandles
contendo um proxy transparente para um WaitHandle em outro domínio de aplicativo.
Exemplos
O exemplo de código a seguir mostra como usar o pool de threads para criar e gravar de forma assíncrona em um grupo de arquivos. Cada operação de gravação é enfileirada como um item de trabalho e sinaliza quando é concluída. O thread principal aguarda que todos os itens sinalizem e saiam.
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
ref class State
{
public:
String^ fileName;
array<Byte>^byteArray;
ManualResetEvent^ manualEvent;
State( String^ fileName, array<Byte>^byteArray, ManualResetEvent^ manualEvent )
: fileName( fileName ), byteArray( byteArray ), manualEvent( manualEvent )
{}
};
ref class Writer
{
private:
static int workItemCount = 0;
Writer(){}
public:
static void WriteToFile( Object^ state )
{
int workItemNumber = workItemCount;
Interlocked::Increment( workItemCount );
Console::WriteLine( "Starting work item {0}.", workItemNumber.ToString() );
State^ stateInfo = dynamic_cast<State^>(state);
FileStream^ fileWriter;
// Create and write to the file.
try
{
fileWriter = gcnew FileStream( stateInfo->fileName,FileMode::Create );
fileWriter->Write( stateInfo->byteArray, 0, stateInfo->byteArray->Length );
}
finally
{
if ( fileWriter != nullptr )
{
fileWriter->Close();
}
// Signal main() that the work item has finished.
Console::WriteLine( "Ending work item {0}.", workItemNumber.ToString() );
stateInfo->manualEvent->Set();
}
}
};
void main()
{
const int numberOfFiles = 5;
String^ dirName = "C:\\TestTest";
String^ fileName;
array<Byte>^byteArray;
Random^ randomGenerator = gcnew Random;
array<ManualResetEvent^>^manualEvents = gcnew array<ManualResetEvent^>(numberOfFiles);
State^ stateInfo;
if ( !Directory::Exists( dirName ) )
{
Directory::CreateDirectory( dirName );
}
// Queue the work items that create and write to the files.
for ( int i = 0; i < numberOfFiles; i++ )
{
fileName = String::Concat( dirName, "\\Test", ((i)).ToString(), ".dat" );
// Create random data to write to the file.
byteArray = gcnew array<Byte>(1000000);
randomGenerator->NextBytes( byteArray );
manualEvents[ i ] = gcnew ManualResetEvent( false );
stateInfo = gcnew State( fileName,byteArray,manualEvents[ i ] );
ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &Writer::WriteToFile ), stateInfo );
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
WaitHandle::WaitAll( manualEvents );
Console::WriteLine( "Files written - main exiting." );
}
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;
class Test
{
static void Main()
{
const int numberOfFiles = 5;
string dirName = @"C:\TestTest";
string fileName;
byte[] byteArray;
Random randomGenerator = new Random();
ManualResetEvent[] manualEvents =
new ManualResetEvent[numberOfFiles];
State stateInfo;
if(!Directory.Exists(dirName))
{
Directory.CreateDirectory(dirName);
}
// Queue the work items that create and write to the files.
for(int i = 0; i < numberOfFiles; i++)
{
fileName = string.Concat(
dirName, @"\Test", i.ToString(), ".dat");
// Create random data to write to the file.
byteArray = new byte[1000000];
randomGenerator.NextBytes(byteArray);
manualEvents[i] = new ManualResetEvent(false);
stateInfo =
new State(fileName, byteArray, manualEvents[i]);
ThreadPool.QueueUserWorkItem(new WaitCallback(
Writer.WriteToFile), stateInfo);
}
// Since ThreadPool threads are background threads,
// wait for the work items to signal before exiting.
WaitHandle.WaitAll(manualEvents);
Console.WriteLine("Files written - main exiting.");
}
}
// Maintain state to pass to WriteToFile.
class State
{
public string fileName;
public byte[] byteArray;
public ManualResetEvent manualEvent;
public State(string fileName, byte[] byteArray,
ManualResetEvent manualEvent)
{
this.fileName = fileName;
this.byteArray = byteArray;
this.manualEvent = manualEvent;
}
}
class Writer
{
static int workItemCount = 0;
Writer() {}
public static void WriteToFile(object state)
{
int workItemNumber = workItemCount;
Interlocked.Increment(ref workItemCount);
Console.WriteLine("Starting work item {0}.",
workItemNumber.ToString());
State stateInfo = (State)state;
FileStream fileWriter = null;
// Create and write to the file.
try
{
fileWriter = new FileStream(
stateInfo.fileName, FileMode.Create);
fileWriter.Write(stateInfo.byteArray,
0, stateInfo.byteArray.Length);
}
finally
{
if(fileWriter != null)
{
fileWriter.Close();
}
// Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.",
workItemNumber.ToString());
stateInfo.manualEvent.Set();
}
}
}
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading
Public Class Test
' WaitHandle.WaitAll requires a multithreaded apartment
' when using multiple wait handles.
<MTAThreadAttribute> _
Shared Sub Main()
Const numberOfFiles As Integer = 5
Dim dirName As String = "C:\TestTest"
Dim fileName As String
Dim byteArray() As Byte
Dim randomGenerator As New Random()
Dim manualEvents(numberOfFiles - 1) As ManualResetEvent
Dim stateInfo As State
If Directory.Exists(dirName) <> True Then
Directory.CreateDirectory(dirName)
End If
' Queue the work items that create and write to the files.
For i As Integer = 0 To numberOfFiles - 1
fileName = String.Concat( _
dirName, "\Test", i.ToString(), ".dat")
' Create random data to write to the file.
byteArray = New Byte(1000000){}
randomGenerator.NextBytes(byteArray)
manualEvents(i) = New ManualResetEvent(false)
stateInfo = _
New State(fileName, byteArray, manualEvents(i))
ThreadPool.QueueUserWorkItem(AddressOf _
Writer.WriteToFile, stateInfo)
Next i
' Since ThreadPool threads are background threads,
' wait for the work items to signal before exiting.
WaitHandle.WaitAll(manualEvents)
Console.WriteLine("Files written - main exiting.")
End Sub
End Class
' Maintain state to pass to WriteToFile.
Public Class State
Public fileName As String
Public byteArray As Byte()
Public manualEvent As ManualResetEvent
Sub New(fileName As String, byteArray() As Byte, _
manualEvent As ManualResetEvent)
Me.fileName = fileName
Me.byteArray = byteArray
Me.manualEvent = manualEvent
End Sub
End Class
Public Class Writer
Private Sub New()
End Sub
Shared workItemCount As Integer = 0
Shared Sub WriteToFile(state As Object)
Dim workItemNumber As Integer = workItemCount
Interlocked.Increment(workItemCount)
Console.WriteLine("Starting work item {0}.", _
workItemNumber.ToString())
Dim stateInfo As State = CType(state, State)
Dim fileWriter As FileStream = Nothing
' Create and write to the file.
Try
fileWriter = New FileStream( _
stateInfo.fileName, FileMode.Create)
fileWriter.Write(stateInfo.byteArray, _
0, stateInfo.byteArray.Length)
Finally
If Not fileWriter Is Nothing Then
fileWriter.Close()
End If
' Signal Main that the work item has finished.
Console.WriteLine("Ending work item {0}.", _
workItemNumber.ToString())
stateInfo.manualEvent.Set()
End Try
End Sub
End Class
Comentários
AbandonedMutexException é novo no .NET Framework versão 2.0. Em versões anteriores, o WaitAll método retorna true
quando um mutex é abandonado. Um mutex abandonado geralmente indica um erro grave de codificação. No caso de um mutex em todo o sistema, pode indicar que um aplicativo foi encerrado abruptamente (por exemplo, usando o Gerenciador de Tarefas do Windows). A exceção contém informações úteis para depuração.
O WaitAll método retorna quando todos os identificadores são sinalizados. Se mais de 64 identificadores forem passados, um NotSupportedException será gerado. Se a matriz contiver duplicatas, a chamada falhará com um DuplicateWaitObjectException.
Chamar essa sobrecarga de método é equivalente a chamar a sobrecarga do WaitAll(WaitHandle[], Int32, Boolean) método e especificar -1 (ou Timeout.Infinite) para e true
para millisecondsTimeout
exitContext
.