WaitHandle.WaitAll 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
等候指定陣列中的所有項目都收到信號。
多載
WaitAll(WaitHandle[], TimeSpan, Boolean) |
等候指定陣列中的所有項目都收到信號,使用 TimeSpan 值來指定時間間隔,並指定是否要先離開同步處理網域,再開始等候。 |
WaitAll(WaitHandle[], Int32, Boolean) |
等候指定陣列中的所有項目都收到信號,使用 Int32 值來指定時間間隔,並指定是否要先離開同步處理網域,再開始等候。 |
WaitAll(WaitHandle[], TimeSpan) |
等候指定陣列中的所有項目都收到信號,使用 TimeSpan 值來指定時間間隔。 |
WaitAll(WaitHandle[], Int32) |
等候指定陣列中的所有項目都收到信號,使用 Int32 值來指定時間間隔。 |
WaitAll(WaitHandle[]) |
等候指定陣列中的所有項目都收到信號。 |
WaitAll(WaitHandle[], TimeSpan, Boolean)
等候指定陣列中的所有項目都收到信號,使用 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
陣列,包含目前執行個體將等候的物件。 這個陣列不能包含相同物件的多個參考。
- exitContext
- Boolean
true
表示在等候 (如果在同步內容中) 前結束內容的同步處理網域,並於之後重新取得,否則為 false
。
傳回
當 waitHandles
中的所有元素都收到訊號時,則為 true
,否則為 false
。
例外狀況
waitHandles
參數為 null
。
-或-
waitHandles
陣列中的一或多個物件為 null
。
-或-
waitHandles
是沒有任何項目的陣列,且 .NET Framework 版本為 2.0 或更新版本。
waitHandles
陣列包含重複的項目。
waitHandles
是沒有任何項目的陣列,且 .NET Framework 版本為 1.0 或 1.1。
由於執行緒結束時未釋放 Mutex,已結束等候。
waitHandles
陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。
範例
下列程式代碼範例示範如何使用線程集區,以異步方式建立和寫入檔案群組。 每個寫入作業都會排入佇列作為工作專案,並在完成時發出訊號。 主線程會等候所有專案發出訊號,然後結束。
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
備註
如果 timeout
為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回 。
如果放棄 Mutex, AbandonedMutexException 則會擲回 。 放棄的 Mutex 通常表示嚴重的編碼錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (,例如使用 Windows 任務管理員) 。 例外狀況包含可用於偵錯的資訊。
方法 WaitAll 會在等候終止時傳回,這表示所有句柄都會發出訊號或發生逾時。 如果傳遞超過 64 個句柄, NotSupportedException 則會擲回 。 如果陣列包含重複專案,呼叫將會失敗。
的最大值 timeout
為 Int32.MaxValue。
結束內容
exitContext
除非從非預設 Managed 內容內呼叫這個方法,否則參數沒有作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果在 ContextBoundObject 目前應用程式域中的堆疊上,您仍可以位於非預設內容中。
當您的程式代碼在非預設內容中執行時,指定 true
會導致 exitContext
線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 線程會在呼叫這個方法完成之後,傳回原始的非預設內容。
當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而且同步處理網域是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫此方法並指定 true
exitContext
,則線程會結束同步處理網域,這可讓呼叫物件的任何成員上封鎖的線程繼續進行。 當這個方法傳回時,發出呼叫的線程必須等候重新進入同步處理網域。
適用於
WaitAll(WaitHandle[], Int32, Boolean)
等候指定陣列中的所有項目都收到信號,使用 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
陣列,包含目前執行個體將等候的物件。 這個陣列無法包含相同物件 (複本) 的多個參考。
- exitContext
- Boolean
true
表示在等候 (如果在同步內容中) 前結束內容的同步處理網域,並於之後重新取得,否則為 false
。
傳回
當 waitHandles
中的所有項目都收到信號時,則為 true
;否則為 false
。
例外狀況
waitHandles
參數為 null
。
-或-
waitHandles
陣列中的一或多個物件為 null
。
-或-
waitHandles
是沒有任何項目的陣列,且 .NET Framework 版本為 2.0 或更新版本。
waitHandles
陣列包含重複的項目。
waitHandles
是沒有任何項目的陣列,且 .NET Framework 版本為 1.0 或 1.1。
millisecondsTimeout
為 -1 以外的負數,表示無限逾時。
由於執行緒結束時未釋放 Mutex,已完成等候。
waitHandles
陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。
範例
下列程式代碼範例示範如何使用線程集區,以異步方式建立和寫入檔案群組。 每個寫入作業都會排入佇列作為工作專案,並在完成時發出訊號。 主線程會等候所有專案發出訊號,然後結束。
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
備註
如果 millisecondsTimeout
為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回 。
如果放棄 Mutex, AbandonedMutexException 則會擲回 。 放棄的 Mutex 通常表示嚴重的編碼錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (,例如使用 Windows 任務管理員) 。 例外狀況包含可用於偵錯的資訊。
方法 WaitAll 會在等候終止時傳回,這表示當發出所有句柄的訊號或發生逾時時。 如果傳遞超過 64 個句柄, NotSupportedException 則會擲回 。 如果陣列中有重複項目,呼叫會失敗並出現 DuplicateWaitObjectException。
結束內容
exitContext
除非從非預設 Managed 內容內呼叫這個方法,否則參數沒有作用。 如果您的線程位於衍生自 ContextBoundObject之類別實例的呼叫內,則Managed內容可以是非預設的。 即使您目前正在不是衍生自 ContextBoundObject的類別上執行方法,例如 String,如果在 ContextBoundObject 目前應用程式域中的堆疊上,您仍可以位於非預設內容中。
當您的程式代碼在非預設內容中執行時,指定 true
會導致 exitContext
線程結束非預設受控內容 (,也就是在執行此方法之前轉換至默認內容) 。 線程會在呼叫這個方法完成之後,傳回原始的非預設內容。
當內容系結類別具有 SynchronizationAttribute 屬性時,結束內容可能會很有用。 在此情況下,類別成員的所有呼叫都會自動同步處理,而且同步處理網域是類別的整個程式代碼主體。 如果成員呼叫堆疊中的程式代碼呼叫此方法並指定 true
exitContext
,則線程會結束同步處理網域,這可讓呼叫物件的任何成員上封鎖的線程繼續進行。 當這個方法傳回時,進行呼叫的線程必須等候重新進入同步處理網域。
適用於
WaitAll(WaitHandle[], TimeSpan)
等候指定陣列中的所有項目都收到信號,使用 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
陣列,包含目前執行個體將等候的物件。 這個陣列不能包含相同物件的多個參考。
傳回
當 waitHandles
中的所有項目都收到信號時,則為 true
;否則為 false
。
例外狀況
waitHandles
參數為 null
。
-或-
waitHandles
陣列中的一或多個物件為 null
。
-或-
waitHandles
是不含任何項目的陣列。
waitHandles
陣列包含重複的項目。
注意:在適用於 Microsoft Store 的 .NET 應用程式或可攜式類別庫中,請改為捕捉基底類別例外狀況 ArgumentException。
由於執行緒結束時未釋放 Mutex,已結束等候。
waitHandles
陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。
備註
如果 timeout
為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回。
方法 WaitAll 會在等候終止時傳回,這表示所有句柄都會發出訊號或發生逾時。 如果傳遞超過 64 個 NotSupportedException 句柄,則會擲回 。 如果陣列包含重複專案,呼叫將會失敗。
最大 timeout
值為 Int32.MaxValue。
呼叫這個方法多載與呼叫 WaitAll(WaitHandle[], TimeSpan, Boolean) 多載和針對 exitContext
指定false
相同。
適用於
WaitAll(WaitHandle[], Int32)
等候指定陣列中的所有項目都收到信號,使用 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
陣列,包含目前執行個體將等候的物件。 這個陣列無法包含相同物件 (複本) 的多個參考。
傳回
當 waitHandles
中的所有項目都收到信號時,則為 true
;否則為 false
。
例外狀況
waitHandles
參數為 null
。
-或-
waitHandles
陣列中的一或多個物件為 null
。
-或-
waitHandles
是不含任何項目的陣列。
waitHandles
陣列包含重複的項目。
注意:在適用於 Microsoft Store 的 .NET 應用程式或可攜式類別庫中,請改為捕捉基底類別例外狀況 ArgumentException。
millisecondsTimeout
為 -1 以外的負數,表示無限逾時。
由於執行緒結束時未釋放 Mutex,已完成等候。
waitHandles
陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。
備註
如果 millisecondsTimeout
為零,則方法不會封鎖。 它會測試等候句柄的狀態,並立即傳回。
方法 WaitAll 會在等候終止時傳回,這表示當發出所有句柄的訊號或發生逾時時。 如果傳遞超過 64 個 NotSupportedException 句柄,則會擲回 。 如果陣列中有重複項目,呼叫會失敗並 DuplicateWaitObjectException出現 。
呼叫這個方法多載與呼叫 WaitAll(WaitHandle[], Int32, Boolean) 多載和針對 exitContext
指定false
相同。
適用於
WaitAll(WaitHandle[])
等候指定陣列中的所有項目都收到信號。
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
陣列,包含目前執行個體將等候的物件。 這個陣列不能包含相同物件的多個參考。
傳回
當 waitHandles
中的所有項目都收到信號時,則為 true
;否則絕不會傳回這個方法。
例外狀況
waitHandles
參數為 null
。 -或-
waitHandles
陣列中的一或多個物件為 null
。
-或-
waitHandles
是沒有任何項目的陣列,且 .NET Framework 版本為 2.0 或更新版本。
waitHandles
陣列包含重複的項目。
注意:在適用於 Microsoft Store 的 .NET 應用程式或可攜式類別庫中,請改為捕捉基底類別例外狀況 ArgumentException。
waitHandles
是沒有任何項目的陣列,且 .NET Framework 版本為 1.0 或 1.1。
由於執行緒結束時未釋放 Mutex,已結束等候。
waitHandles
陣列在另一個應用程式定義域中包含 WaitHandle 的 Transparent Proxy。
範例
下列程式代碼範例示範如何使用線程集區,以異步方式建立和寫入檔案群組。 每個寫入作業都會排入佇列作為工作專案,並在完成時發出訊號。 主線程會等候所有專案發出訊號,然後結束。
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
備註
AbandonedMutexException 是 .NET Framework 2.0 版的新功能。 在舊版中 WaitAll ,方法會在 true
放棄 Mutex 時傳回。 已放棄的 Mutex 通常表示嚴重的程式代碼撰寫錯誤。 在全系統 Mutex 的情況下,它可能表示應用程式已突然終止 (例如,使用 Windows 任務管理員) 。 例外狀況包含適用於偵錯的資訊。
當發出所有句柄的訊號時,方法 WaitAll 會傳回 。 如果傳遞超過 64 個 NotSupportedException 句柄,則會擲回 。 如果陣列包含重複項目,呼叫會失敗並 DuplicateWaitObjectException出現 。
呼叫這個方法多載相當於呼叫 WaitAll(WaitHandle[], Int32, Boolean) 方法多載,併為 和 指定 -1 (或 Timeout.Infinite) millisecondsTimeout
true
exitContext
。