WaitHandle.WaitAll Метод
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Ожидает получения сигнала для всех элементов в указанном массиве.
Перегрузки
| Имя | Описание |
|---|---|
| WaitAll(WaitHandle[], TimeSpan, Boolean) |
Ожидает, чтобы все элементы в указанном массиве получали сигнал, используя TimeSpan значение для указания интервала времени и указывая, следует ли выйти из домена синхронизации перед ожиданием. |
| WaitAll(WaitHandle[], Int32, Boolean) |
Ожидает, чтобы все элементы в указанном массиве получали сигнал, используя Int32 значение, чтобы указать интервал времени и указать, следует ли выйти из домена синхронизации перед ожиданием. |
| WaitAll(WaitHandle[], TimeSpan) |
Ожидает, чтобы все элементы в указанном массиве получали сигнал, используя TimeSpan значение для указания интервала времени. |
| WaitAll(WaitHandle[], Int32) |
Ожидает, чтобы все элементы в указанном массиве получали сигнал, используя Int32 значение для указания интервала времени. |
| WaitAll(WaitHandle[]) |
Ожидает получения сигнала для всех элементов в указанном массиве. |
WaitAll(WaitHandle[], TimeSpan, Boolean)
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Ожидает, чтобы все элементы в указанном массиве получали сигнал, используя TimeSpan значение для указания интервала времени и указывая, следует ли выйти из домена синхронизации перед ожиданием.
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
Параметры
- waitHandles
- WaitHandle[]
WaitHandle Массив, содержащий объекты, для которых текущий экземпляр будет ожидать. Этот массив не может содержать несколько ссылок на один и тот же объект.
- timeout
- TimeSpan
Значение TimeSpan , представляющее количество миллисекунда, которое нужно ожидать, или значение TimeSpan , представляющее -1 миллисекундах, для ожидания на неопределенный срок.
- exitContext
- Boolean
true чтобы выйти из домена синхронизации для контекста перед ожиданием (если в синхронизированном контексте) и повторно приступить к нему; falseв противном случае .
Возвращаемое значение
true Значение , если каждый элемент в waitHandles получил сигнал; в противном случае false.
Исключения
Параметр waitHandles имеет значение null.
–или–
Один или несколько объектов в массиве waitHandlesnull.
–или–
waitHandles — это массив без элементов, а версия .NET Framework — 2.0 или более поздняя.
Массив waitHandles содержит элементы, повторяющиеся.
Число объектов больше waitHandles , чем разрешение системы.
–или–
Атрибут STAThreadAttribute применяется к процедуре потока для текущего потока и waitHandles содержит несколько элементов.
waitHandles — это массив без элементов, а версия .NET Framework — 1.0 или 1.1.
timeout — отрицательное число, отличное от -1 миллисекундах, которое представляет бесконечное время ожидания.
–или–
timeout больше int32.MaxValue.
Ожидание завершено, так как поток завершился без освобождения мьютекса.
Массив waitHandles содержит прозрачный прокси-сервер для другого WaitHandle домена приложения.
Примеры
В следующем примере кода показано, как использовать пул потоков для асинхронного создания и записи в группу файлов. Каждая операция записи помещается в очередь как рабочий элемент и сигнализирует о завершении. Основной поток ожидает, пока все элементы будут сигнализировать, а затем завершает работу.
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
Комментарии
Если timeout значение равно нулю, метод не блокируется. Он проверяет состояние дескрипторов ожидания и возвращается немедленно.
При отказе AbandonedMutexException от мьютекса создается исключение. Заброшенный мьютекс часто указывает на серьезную ошибку кодирования. В случае с мьютексом на уровне системы может быть указано, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.
Метод WaitAll возвращается при завершении ожидания, что означает, что все дескрипторы сигнализируются или происходит время ожидания. Если передаются более 64 дескрипторов, NotSupportedException создается исключение. Если массив содержит повторяющиеся данные, вызов завершится ошибкой.
Максимальное значение для timeoutInt32.MaxValue.
Выход из контекста
Параметр exitContext не действует, если этот метод не вызывается внутри недефакулируемых управляемых контекстов. Управляемый контекст может быть несознанным, если поток находится внутри вызова экземпляра класса, производного от ContextBoundObject. Даже если вы в настоящее время выполняете метод в классе, который не является производным от ContextBoundObject, например String, вы можете находиться в неразделаемом контексте, если ContextBoundObject он находится в стеке в текущем домене приложения.
При выполнении кода в недефакционном контексте, указывая true для exitContext того, чтобы поток вышел из недефаультного управляемого контекста (т. е. для перехода в контекст по умолчанию) перед выполнением этого метода. Поток возвращается в исходный недефакторный контекст после завершения вызова этого метода.
Выход из контекста может оказаться полезным, если класс с привязкой контекста имеет SynchronizationAttribute атрибут. В этом случае все вызовы к членам класса синхронизируются автоматически, а домен синхронизации — весь текст кода для класса. Если код в стеке вызовов члена вызывает этот метод и указывает true для exitContextэтого, поток выходит из домена синхронизации, что позволяет потоку, блокированному при вызове любого члена объекта, продолжить. Когда этот метод возвращается, поток, который сделал вызов, должен ждать повторного приема домена синхронизации.
Применяется к
WaitAll(WaitHandle[], Int32, Boolean)
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Ожидает, чтобы все элементы в указанном массиве получали сигнал, используя Int32 значение, чтобы указать интервал времени и указать, следует ли выйти из домена синхронизации перед ожиданием.
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
Параметры
- waitHandles
- WaitHandle[]
WaitHandle Массив, содержащий объекты, для которых текущий экземпляр будет ожидать. Этот массив не может содержать несколько ссылок на один и тот же объект (дубликаты).
- millisecondsTimeout
- Int32
Количество миллисекунда, ожидающее или Infinite (-1) для ожидания на неопределенный срок.
- exitContext
- Boolean
true чтобы выйти из домена синхронизации для контекста перед ожиданием (если в синхронизированном контексте) и повторно приступить к нему; falseв противном случае .
Возвращаемое значение
trueЗначение , falseесли каждый элемент в waitHandles получил сигнал; в противном случае .
Исключения
Параметр waitHandles имеет значение null.
–или–
Один или несколько объектов в массиве waitHandlesnull.
–или–
waitHandles — это массив без элементов, а версия .NET Framework — 2.0 или более поздняя.
Массив waitHandles содержит элементы, повторяющиеся.
Число объектов больше waitHandles , чем разрешение системы.
–или–
Текущий поток находится в STA состоянии и waitHandles содержит несколько элементов.
waitHandles — это массив без элементов, а версия .NET Framework — 1.0 или 1.1.
millisecondsTimeout — отрицательное число, отличное от -1, которое представляет бесконечное время ожидания.
Ожидание завершено, так как поток завершился без освобождения мьютекса.
Массив waitHandles содержит прозрачный прокси-сервер для другого WaitHandle домена приложения.
Примеры
В следующем примере кода показано, как использовать пул потоков для асинхронного создания и записи в группу файлов. Каждая операция записи помещается в очередь как рабочий элемент и сигнализирует о завершении. Основной поток ожидает, пока все элементы будут сигнализировать, а затем завершает работу.
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
Комментарии
Если millisecondsTimeout значение равно нулю, метод не блокируется. Он проверяет состояние дескрипторов ожидания и возвращается немедленно.
При отказе AbandonedMutexException от мьютекса создается исключение. Заброшенный мьютекс часто указывает на серьезную ошибку кодирования. В случае с мьютексом на уровне системы может быть указано, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.
Метод WaitAll возвращается при завершении ожидания, что означает, что все дескрипторы сигнализируются или при истечении времени ожидания. Если передаются более 64 дескрипторов, NotSupportedException создается исключение. Если в массиве есть дубликаты, вызов завершается ошибкой DuplicateWaitObjectException.
Выход из контекста
Параметр exitContext не действует, если этот метод не вызывается внутри недефакулируемых управляемых контекстов. Управляемый контекст может быть несознанным, если поток находится внутри вызова экземпляра класса, производного от ContextBoundObject. Даже если вы в настоящее время выполняете метод в классе, который не является производным от ContextBoundObject, например String, вы можете находиться в неразделаемом контексте, если ContextBoundObject он находится в стеке в текущем домене приложения.
При выполнении кода в недефакционном контексте, указывая true для exitContext того, чтобы поток вышел из недефаультного управляемого контекста (т. е. для перехода в контекст по умолчанию) перед выполнением этого метода. Поток возвращается в исходный недефакторный контекст после завершения вызова этого метода.
Выход из контекста может оказаться полезным, если класс с привязкой контекста имеет SynchronizationAttribute атрибут. В этом случае все вызовы к членам класса синхронизируются автоматически, а домен синхронизации — весь текст кода для класса. Если код в стеке вызовов члена вызывает этот метод и указывает true для exitContextэтого, поток выходит из домена синхронизации, что позволяет потоку, блокированному при вызове любого члена объекта, продолжить. Когда этот метод возвращается, поток, который сделал вызов, должен ждать повторного приема домена синхронизации.
Применяется к
WaitAll(WaitHandle[], TimeSpan)
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Ожидает, чтобы все элементы в указанном массиве получали сигнал, используя TimeSpan значение для указания интервала времени.
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
Параметры
- waitHandles
- WaitHandle[]
WaitHandle Массив, содержащий объекты, для которых текущий экземпляр будет ожидать. Этот массив не может содержать несколько ссылок на один и тот же объект.
- timeout
- TimeSpan
Значение TimeSpan , представляющее количество миллисекунда, которое нужно ожидать, или значение TimeSpan , представляющее -1 миллисекундах, для ожидания на неопределенный срок.
Возвращаемое значение
trueЗначение , falseесли каждый элемент в waitHandles получил сигнал; в противном случае .
Исключения
Параметр waitHandles имеет значение null.
–или–
Один или несколько объектов в массиве waitHandlesnull.
–или–
waitHandles — это массив без элементов.
Массив waitHandles содержит элементы, повторяющиеся.
Число объектов больше waitHandles , чем разрешение системы.
–или–
Текущий поток находится в STA состоянии и waitHandles содержит несколько элементов.
timeout — отрицательное число, отличное от -1 миллисекундах, которое представляет бесконечное время ожидания.
–или–
timeout больше int32.MaxValue.
Ожидание завершено, так как поток завершился без освобождения мьютекса.
Массив waitHandles содержит прозрачный прокси-сервер для другого WaitHandle домена приложения.
Комментарии
Если timeout значение равно нулю, метод не блокируется. Он проверяет состояние дескрипторов ожидания и возвращается немедленно.
Метод WaitAll возвращается при завершении ожидания, что означает, что все дескрипторы сигнализируются или происходит время ожидания. Если передаются более 64 дескрипторов, NotSupportedException создается исключение. Если массив содержит повторяющиеся данные, вызов завершится ошибкой.
Максимальное значение для timeoutInt32.MaxValue.
Вызов перегрузки этого метода совпадает с вызовом перегрузки WaitAll(WaitHandle[], TimeSpan, Boolean) и указанием false для exitContext.
Применяется к
WaitAll(WaitHandle[], Int32)
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Ожидает, чтобы все элементы в указанном массиве получали сигнал, используя Int32 значение для указания интервала времени.
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
Параметры
- waitHandles
- WaitHandle[]
WaitHandle Массив, содержащий объекты, для которых текущий экземпляр будет ожидать. Этот массив не может содержать несколько ссылок на один и тот же объект (дубликаты).
- millisecondsTimeout
- Int32
Количество миллисекунда, ожидающее или Infinite (-1) для ожидания на неопределенный срок.
Возвращаемое значение
trueЗначение , falseесли каждый элемент в waitHandles получил сигнал; в противном случае .
Исключения
Параметр waitHandles имеет значение null.
–или–
Один или несколько объектов в массиве waitHandlesnull.
–или–
waitHandles — это массив без элементов.
Массив waitHandles содержит элементы, повторяющиеся.
Число объектов больше waitHandles , чем разрешение системы.
–или–
Текущий поток находится в STA состоянии и waitHandles содержит несколько элементов.
millisecondsTimeout — отрицательное число, отличное от -1, которое представляет бесконечное время ожидания.
Ожидание завершено, так как поток завершился без освобождения мьютекса.
Массив waitHandles содержит прозрачный прокси-сервер для другого WaitHandle домена приложения.
Комментарии
Если millisecondsTimeout значение равно нулю, метод не блокируется. Он проверяет состояние дескрипторов ожидания и возвращается немедленно.
Метод WaitAll возвращается при завершении ожидания, что означает, что все дескрипторы сигнализируются или при истечении времени ожидания. Если передаются более 64 дескрипторов, NotSupportedException создается исключение. Если в массиве есть дубликаты, вызов завершается ошибкой DuplicateWaitObjectException.
Вызов перегрузки этого метода совпадает с вызовом перегрузки WaitAll(WaitHandle[], Int32, Boolean) и указанием false для exitContext.
Применяется к
WaitAll(WaitHandle[])
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
- Исходный код:
- WaitHandle.cs
Ожидает получения сигнала для всех элементов в указанном массиве.
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
Параметры
- waitHandles
- WaitHandle[]
WaitHandle Массив, содержащий объекты, для которых текущий экземпляр будет ожидать. Этот массив не может содержать несколько ссылок на один и тот же объект.
Возвращаемое значение
true Когда каждый элемент в waitHandles получил сигнал; в противном случае метод никогда не возвращается.
Исключения
Параметр waitHandles имеет значение null. –или–
Один или несколько объектов в массиве waitHandlesnull.
–или–
waitHandles — это массив без элементов, а версия .NET Framework — 2.0 или более поздняя.
Массив waitHandles содержит элементы, повторяющиеся.
Число объектов больше waitHandles , чем разрешение системы.
–или–
Текущий поток находится в STA состоянии и waitHandles содержит несколько элементов.
waitHandles — это массив без элементов, а версия .NET Framework — 1.0 или 1.1.
Ожидание завершено, так как поток завершился без освобождения мьютекса.
Массив waitHandles содержит прозрачный прокси-сервер для другого WaitHandle домена приложения.
Примеры
В следующем примере кода показано, как использовать пул потоков для асинхронного создания и записи в группу файлов. Каждая операция записи помещается в очередь как рабочий элемент и сигнализирует о завершении. Основной поток ожидает, пока все элементы будут сигнализировать, а затем завершает работу.
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
Комментарии
AbandonedMutexException является новым в .NET Framework версии 2.0. В предыдущих версиях WaitAll метод возвращается true при отказе от мьютекса. Заброшенный мьютекс часто указывает на серьезную ошибку кодирования. В случае с мьютексом на уровне системы может быть указано, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.
Метод WaitAll возвращается при сигнале всех дескрипторов. Если передаются более 64 дескрипторов, NotSupportedException создается исключение. Если массив содержит дубликаты, вызов завершается ошибкой DuplicateWaitObjectException.
Вызов перегрузки этого метода эквивалентен вызову WaitAll(WaitHandle[], Int32, Boolean) перегрузки метода и указанию -1 (или Timeout.Infinite) для millisecondsTimeout и true для exitContext.