Прочитать на английском

Поделиться через


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

Ожидает получения сигнала всеми элементами заданного массива, используя значение типа TimeSpan для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания.

public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout, bool exitContext);

Параметры

waitHandles
WaitHandle[]

Массив WaitHandle, содержащий объекты, ожидаемые текущим экземпляром. Этот массив не может содержать несколько ссылок на один и тот же объект.

timeout
TimeSpan

Объект TimeSpan, представляющий время ожидания в миллисекундах, или объект TimeSpan, представляющий -1 миллисекунду для неограниченного ожидания.

exitContext
Boolean

Значение true для выхода из домена синхронизации в текущем контексте перед ожиданием (в синхронизированном контексте) с его последующим повторным получением; в противном случае — false.

Возвращаемое значение

Значение true, когда каждый элемент массива waitHandles получил сигнал; иначе — false.

Исключения

Параметр waitHandles имеет значение null.

-или-

Один или несколько объектов массива waitHandles имеют значение null.

-или-

Массив 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();
        }
    }
}

Комментарии

Если timeout равно нулю, метод не блокируется. Он проверяет состояние дескрипторов ожидания и возвращается немедленно.

При отказе от мьютекса AbandonedMutexException создается исключение . Отказ от мьютекса часто указывает на серьезную ошибку кодирования. В случае системного мьютекса это может означать, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.

Метод WaitAll возвращает, когда ожидание завершается. Это означает, что все дескрипторы получают сигнал или возникает время ожидания. Если передается более 64 дескрипторов, NotSupportedException возникает исключение . Если массив содержит дубликаты, вызов завершится ошибкой.

Примечание

Метод WaitAll не поддерживается в потоках в STA состоянии.

Максимальное значение для timeoutInt32.MaxValue.

Выход из контекста

Параметр exitContext не действует, если этот метод не вызывается из нестандартного управляемого контекста. Управляемый контекст может быть неразрешен, если поток находится внутри вызова экземпляра класса, производного от ContextBoundObject. Даже если вы в настоящее время выполняете метод в классе, который не является производным от ContextBoundObject, например String, вы можете находиться в контексте, не являющемся стандартным, если ContextBoundObject находится в стеке в текущем домене приложения.

При выполнении кода в контексте, не являющегося стандартным, указание true для exitContext приводит к тому, что перед выполнением этого метода поток выйдет из нестандартного управляемого контекста (т. е. для перехода в контекст по умолчанию). Поток возвращается в исходный контекст nondefault после завершения вызова этого метода.

Выход из контекста может быть полезен, если связанный с контекстом класс имеет SynchronizationAttribute атрибут . В этом случае все вызовы членов класса синхронизируются автоматически, а домен синхронизации — это весь текст кода для класса. Если код в стеке вызовов true члена вызывает этот метод и указывает для exitContext, поток выходит из домена синхронизации, что позволяет потоку, заблокированном при вызове любого члена объекта, продолжить работу. При возврате этого метода поток, который сделал вызов, должен дождаться повторного ввести домен синхронизации.

Применяется к

.NET 9 и другие версии
Продукт Версии
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

WaitAll(WaitHandle[], Int32, Boolean)

Исходный код:
WaitHandle.cs
Исходный код:
WaitHandle.cs
Исходный код:
WaitHandle.cs

Ожидает получения сигнала всеми элементами заданного массива, используя значение типа Int32 для задания интервала времени и указывая, следует ли выйти из домена синхронизации до начала ожидания.

public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext);

Параметры

waitHandles
WaitHandle[]

Массив WaitHandle, содержащий объекты, ожидаемые текущим экземпляром. Данный массив не может содержать несколько ссылок на один и тот же объект (дубликатов).

millisecondsTimeout
Int32

Время ожидания в миллисекундах или функция Infinite (-1) в случае неограниченного времени ожидания.

exitContext
Boolean

Значение true для выхода из домена синхронизации в текущем контексте перед ожиданием (в синхронизированном контексте) с его последующим повторным получением; в противном случае — false.

Возвращаемое значение

Значение true, если каждый элемент массива waitHandles получил сигнал; в противном случае значение false.

Исключения

Параметр waitHandles имеет значение null.

-или-

Один или несколько объектов массива waitHandles имеют значение null.

-или-

Массив 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();
        }
    }
}

Комментарии

Если millisecondsTimeout равно нулю, метод не блокируется. Он проверяет состояние дескрипторов ожидания и возвращается немедленно.

При отказе от мьютекса AbandonedMutexException создается исключение . Отказ от мьютекса часто указывает на серьезную ошибку кодирования. В случае системного мьютекса это может означать, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.

Метод WaitAll возвращает значение , когда ожидание завершается, то есть, когда все дескрипторы сигнализируют, или при истечении времени ожидания. Если передается более 64 дескрипторов, NotSupportedException возникает исключение . Если в массиве есть дубликаты, вызов завершается ошибкой DuplicateWaitObjectExceptionс .

Примечание

Метод WaitAll не поддерживается в потоках в STA состоянии.

Выход из контекста

Параметр exitContext не действует, если этот метод не вызывается из нестандартного управляемого контекста. Управляемый контекст может быть неразрешен, если поток находится внутри вызова экземпляра класса, производного от ContextBoundObject. Даже если вы в настоящее время выполняете метод в классе, который не является производным от ContextBoundObject, например String, вы можете находиться в контексте, не являющемся стандартным, если ContextBoundObject находится в стеке в текущем домене приложения.

При выполнении кода в контексте, не являющегося стандартным, указание true для exitContext приводит к тому, что перед выполнением этого метода поток выйдет из нестандартного управляемого контекста (т. е. для перехода в контекст по умолчанию). Поток возвращается в исходный контекст nondefault после завершения вызова этого метода.

Выход из контекста может быть полезен, если связанный с контекстом класс имеет SynchronizationAttribute атрибут . В этом случае все вызовы членов класса синхронизируются автоматически, а домен синхронизации — это весь текст кода для класса. Если код в стеке вызовов true члена вызывает этот метод и указывает для exitContext, поток выходит из домена синхронизации, что позволяет потоку, заблокированном при вызове любого члена объекта, продолжить работу. При возврате этого метода поток, который сделал вызов, должен дождаться повторного ввести домен синхронизации.

Применяется к

.NET 9 и другие версии
Продукт Версии
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1

WaitAll(WaitHandle[], TimeSpan)

Исходный код:
WaitHandle.cs
Исходный код:
WaitHandle.cs
Исходный код:
WaitHandle.cs

Ожидает получения сигнала всеми элементами заданного массива, используя значение TimeSpan для указания интервала времени.

public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, TimeSpan timeout);

Параметры

waitHandles
WaitHandle[]

Массив WaitHandle, содержащий объекты, ожидаемые текущим экземпляром. Этот массив не может содержать несколько ссылок на один и тот же объект.

timeout
TimeSpan

Объект TimeSpan, представляющий время ожидания в миллисекундах, или объект TimeSpan, представляющий -1 миллисекунду для неограниченного ожидания.

Возвращаемое значение

Значение true, если каждый элемент массива waitHandles получил сигнал; в противном случае значение false.

Исключения

Параметр waitHandles имеет значение null.

-или-

Один или несколько объектов массива waitHandles имеют значение null.

-или-

В массиве waitHandles отсутствуют элементы.

Массив waitHandles содержит повторяющиеся элементы.

Примечание. В .NET для приложений Магазина Windows или в переносимой библиотеке классов перехватите исключение базового класса ArgumentException.

Массив waitHandles содержит больше объектов, чем разрешено системой.

-или-

Текущий поток находится в состоянии STA, а waitHandles содержит несколько элементов.

timeout является отрицательным числом, отличным от -1 миллисекунды, которое представляет неограниченное время ожидания.

-или-

timeout больше, чем Int32.MaxValue.

Ожидание прервано, так как поток завершил работу, не освободив мьютекс.

Массив waitHandles содержит прозрачный прокси для элемента WaitHandle в другом домене приложения.

Комментарии

Если timeout равно нулю, метод не блокируется. Он проверяет состояние дескрипторов ожидания и возвращается немедленно.

Метод WaitAll возвращает, когда ожидание завершается. Это означает, что все дескрипторы получают сигнал или возникает время ожидания. Если передается более 64 дескрипторов, NotSupportedException возникает исключение . Если массив содержит дубликаты, вызов завершится ошибкой.

Примечание

Метод WaitAll не поддерживается в потоках в STA состоянии.

Максимальное значение для timeoutInt32.MaxValue.

Вызов перегрузки этого метода совпадает с вызовом перегрузки WaitAll(WaitHandle[], TimeSpan, Boolean) и указанием false для exitContext.

Применяется к

.NET 9 и другие версии
Продукт Версии
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

WaitAll(WaitHandle[], Int32)

Исходный код:
WaitHandle.cs
Исходный код:
WaitHandle.cs
Исходный код:
WaitHandle.cs

Ожидает получения сигнала всеми элементами заданного массива, используя значение Int32 для указания интервала времени.

public static bool WaitAll (System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout);

Параметры

waitHandles
WaitHandle[]

Массив WaitHandle, содержащий объекты, ожидаемые текущим экземпляром. Данный массив не может содержать несколько ссылок на один и тот же объект (дубликатов).

millisecondsTimeout
Int32

Время ожидания в миллисекундах или функция Infinite (-1) в случае неограниченного времени ожидания.

Возвращаемое значение

Значение true, если каждый элемент массива waitHandles получил сигнал; в противном случае значение false.

Исключения

Параметр waitHandles имеет значение null.

-или-

Один или несколько объектов массива waitHandles имеют значение null.

-или-

В массиве waitHandles отсутствуют элементы.

Массив waitHandles содержит повторяющиеся элементы.

Примечание. В .NET для приложений Магазина Windows или в переносимой библиотеке классов перехватите исключение базового класса ArgumentException.

Массив waitHandles содержит больше объектов, чем разрешено системой.

-или-

Текущий поток находится в состоянии STA, а waitHandles содержит несколько элементов.

Параметр millisecondsTimeout является отрицательным числом, отличным от –1, что означает бесконечное время ожидания.

Ожидание закончилось, так как поток завершил работу, не освободив мьютекс.

Массив waitHandles содержит прозрачный прокси для элемента WaitHandle в другом домене приложения.

Комментарии

Если millisecondsTimeout равно нулю, метод не блокируется. Он проверяет состояние дескрипторов ожидания и возвращается немедленно.

Метод WaitAll возвращает значение , когда ожидание завершается, то есть, когда все дескрипторы сигнализируют, или при истечении времени ожидания. Если передается более 64 дескрипторов, NotSupportedException возникает исключение . Если в массиве есть дубликаты, вызов завершается ошибкой DuplicateWaitObjectExceptionс .

Примечание

Метод WaitAll не поддерживается в потоках в STA состоянии.

Вызов перегрузки этого метода совпадает с вызовом перегрузки WaitAll(WaitHandle[], Int32, Boolean) и указанием false для exitContext.

Применяется к

.NET 9 и другие версии
Продукт Версии
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

WaitAll(WaitHandle[])

Исходный код:
WaitHandle.cs
Исходный код:
WaitHandle.cs
Исходный код:
WaitHandle.cs

Ожидает получения сигнала всеми элементами заданного массива.

public static bool WaitAll (System.Threading.WaitHandle[] waitHandles);

Параметры

waitHandles
WaitHandle[]

Массив WaitHandle, содержащий объекты, ожидаемые текущим экземпляром. Этот массив не может содержать несколько ссылок на один и тот же объект.

Возвращаемое значение

true, когда каждый элемент waitHandles получил сигнал. В противном случае возврат из метода не происходит.

Исключения

Параметр waitHandles имеет значение null. -или-

Один или несколько объектов массива waitHandles имеют значение null.

-или-

Массив waitHandles не содержит элементов, и используется платформа .NET Framework версии 2.0 или более поздней.

Массив waitHandles содержит повторяющиеся элементы.

Примечание. В .NET для приложений Магазина Windows или в переносимой библиотеке классов перехватите исключение базового класса ArgumentException.

Массив 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();
        }
    }
}

Комментарии

AbandonedMutexException является новым в .NET Framework версии 2.0. В предыдущих версиях метод возвращает значение true при WaitAll отказе от мьютекса. Отказ от мьютекса часто указывает на серьезную ошибку кодирования. В случае системного мьютекса это может означать, что приложение было внезапно завершено (например, с помощью диспетчера задач Windows). Исключение содержит сведения, полезные для отладки.

Метод WaitAll возвращает, когда все дескрипторы получают сигнал. Если передается более 64 дескрипторов, NotSupportedException возникает исключение . Если массив содержит дубликаты, вызов завершается ошибкой DuplicateWaitObjectExceptionс .

Примечание

Метод WaitAll не поддерживается в потоках в STA состоянии.

Вызов перегрузки этого метода эквивалентен вызову перегрузки WaitAll(WaitHandle[], Int32, Boolean) метода и указанию -1 (или Timeout.Infinite) для millisecondsTimeout и true для exitContext.

Применяется к

.NET 9 и другие версии
Продукт Версии
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0