更新:2007 年 11 月
命名空間:
System.Threading 組件:
mscorlib (在 mscorlib.dll 中)
Public Shared Function WaitAll ( _
waitHandles As WaitHandle() _
) As Boolean
Dim waitHandles As WaitHandle()
Dim returnValue As Boolean
returnValue = WaitHandle.WaitAll(waitHandles)
public static bool WaitAll(
WaitHandle[] waitHandles
)
public:
static bool WaitAll(
array<WaitHandle^>^ waitHandles
)
public static boolean WaitAll(
WaitHandle[] waitHandles
)
public static function WaitAll(
waitHandles : WaitHandle[]
) : boolean
AbandonedMutexException 是 .NET Framework 2.0 版的新功能。在先前版本中,放棄 Mutex 時,WaitAll 方法會傳回 true。已放棄的 Mutex 通常會指出嚴重的程式碼錯誤。在系統範圍 Mutex 的情況中,它可能會指出應用程式已意外結束 (例如,使用 [Windows 工作管理員])。例外狀況包含偵錯的有用資訊。
當所有的控制代碼都收到信號後,會傳回 WaitAll 方法。有些實作 (Implementation) 的情況是,如果傳遞超過 64 個控制代碼,會擲回 NotSupportedException。如果陣列中包含重複的元素,則呼叫會失敗,且傳回 DuplicateWaitObjectException。
呼叫這個方法多載相當於呼叫 WaitAll(array<WaitHandle>[]()[], Int32, Boolean) 方法多載以及為 millisecondsTimeout 指定 -1 (或 Timeout..::.Infinite),且為 exitContext 指定 true。
下列程式碼範例會示範了如何使用執行緒集區,以非同步方式來建立和寫入一組檔案。每一個寫入作業會佇列成一個工作項目,並於完成時發出信號。主要的執行緒會等到所有項目都發出完成訊號之後才會結束。
Imports System
Imports System.IO
Imports System.Security.Permissions
Imports System.Threading
' Request permission to create and write files to C:\TestTest.
<Assembly: FileIOPermissionAttribute(SecurityAction.RequestMinimum, _
All := "C:\TestTest")>
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
using System;
using System.IO;
using System.Security.Permissions;
using System.Threading;
// Request permission to create and write files to C:\TestTest.
[assembly: FileIOPermissionAttribute(SecurityAction.RequestMinimum,
All = @"C:\TestTest")]
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();
}
}
}
using namespace System;
using namespace System::IO;
using namespace System::Security::Permissions;
using namespace System::Threading;
// Request permission to create and write files to C:\TestTest.
// Maintain state to pass to WriteToFile.
[assembly:FileIOPermissionAttribute(SecurityAction::RequestMinimum,
All="C:\\TestTest")];
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." );
}
import System.*;
import System.IO.*;
import System.Security.Permissions.*;
import System.Threading.*;
import System.Threading.Thread;
// Request permission to create and write files to C:\TestTest.
/** @assembly FileIOPermissionAttribute(SecurityAction.RequestMinimum,
All = "C:\\TestTest")
*/
class Test
{
public static void main(String[] args)
{
final int numberOfFiles = 5;
String dirName = "C:\\TestTest";
String fileName;
ubyte 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", String.valueOf(i),
".dat");
// Create random data to write to the file.
byteArray = new ubyte[1000000];
randomGenerator.NextBytes(byteArray);
manualEvents.set_Item(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.");
} //main
} //Test
// Maintain state to pass to WriteToFile.
class State
{
public String fileName;
public ubyte byteArray[];
public ManualResetEvent manualEvent;
public State(String fileName, ubyte byteArray[],
ManualResetEvent manualEvent)
{
this.fileName = fileName;
this.byteArray = byteArray;
this.manualEvent = manualEvent;
} //State
} //State
class Writer
{
private static int workItemCount = 0;
Writer()
{
} //Writer
public static void WriteToFile(Object state)
{
int workItemNumber = workItemCount;
Interlocked.Increment(workItemCount);
Console.WriteLine("Starting work item {0}.",
String.valueOf(workItemNumber));
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}.",
String.valueOf(workItemNumber));
stateInfo.manualEvent.Set();
}
} //WriteToFile
} //Writer
Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98
.NET Framework 和 .NET Compact Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱 .NET Framework 系統需求。
.NET Framework
支援版本:3.5、3.0、2.0、1.1、1.0
參考