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

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


WaitHandle.WaitOne Метод

Определение

Блокирует текущий поток до получения сигнала объектом WaitHandle.

Перегрузки

WaitOne()

Блокирует текущий поток до получения сигнала объектом WaitHandle.

WaitOne(Int32)

Блокирует текущий поток до получения текущим дескриптором WaitHandle сигнала, используя 32-разрядное целое число со знаком для указания интервала времени в миллисекундах.

WaitOne(TimeSpan)

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

WaitOne(Int32, Boolean)

Блокирует текущий поток до получения сигнала текущим объектом WaitHandle, используя 32-разрядное целое число со знаком для задания периода времени и указывая, следует ли выйти из домена синхронизации до начала ожидания.

WaitOne(TimeSpan, Boolean)

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

WaitOne()

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

Блокирует текущий поток до получения сигнала объектом WaitHandle.

C#
public virtual bool WaitOne ();

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

Значение true, если текущий экземпляр получает сигнал. Пока текущий экземпляр не сигнализирует, метод WaitOne() не возвращает управление.

Исключения

Текущий экземпляр уже удален.

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

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

Примеры

В следующем примере кода показано, как использовать дескриптор ожидания, чтобы не допустить завершения процесса, пока он ожидает завершения выполнения фонового потока.

C#
using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        autoEvent.WaitOne();
        Console.WriteLine("Work method signaled.\nMain ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}

Комментарии

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

Вызывающий объект этого метода блокируется на неопределенный срок, пока текущий экземпляр не получит сигнал. Используйте этот метод для блокировки до тех пор, пока WaitHandle не получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.

Вызов перегрузки этого метода эквивалентен вызову перегрузки WaitOne(Int32, Boolean) метода и указанию -1 или Timeout.Infinite для первого параметра и false для второго параметра.

Переопределите этот метод, чтобы настроить поведение производных классов.

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

.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

WaitOne(Int32)

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

Блокирует текущий поток до получения текущим дескриптором WaitHandle сигнала, используя 32-разрядное целое число со знаком для указания интервала времени в миллисекундах.

C#
public virtual bool WaitOne (int millisecondsTimeout);

Параметры

millisecondsTimeout
Int32

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

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

Значение true при получении сигнала текущим экземпляром; в противном случае — значение false.

Исключения

Текущий экземпляр уже удален.

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

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

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

Примеры

В следующем примере кода показано, как использовать дескриптор ожидания, чтобы не допустить завершения процесса, пока он ожидает завершения выполнения фонового потока.

C#
using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        if(autoEvent.WaitOne(1000))
        {
            Console.WriteLine("Work method signaled.");
        }
        else
        {
            Console.WriteLine("Timed out waiting for work " +
                "method to signal.");
        }
        Console.WriteLine("Main ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}

Комментарии

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

Вызывающий объект этого метода блокируется до тех пор, пока текущий экземпляр не получит сигнал или не наступает время ожидания. Используйте этот метод для блокировки до тех пор, пока WaitHandle не получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.

Переопределите этот метод, чтобы настроить поведение производных классов.

Вызов перегрузки этого метода совпадает с вызовом перегрузки WaitOne(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

WaitOne(TimeSpan)

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

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

C#
public virtual bool WaitOne (TimeSpan timeout);

Параметры

timeout
TimeSpan

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

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

Значение true при получении сигнала текущим экземпляром; в противном случае — значение false.

Исключения

Текущий экземпляр уже удален.

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

-или-

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

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

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

Комментарии

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

Вызывающий объект этого метода блокируется до тех пор, пока текущий экземпляр не получит сигнал или не наступает время ожидания. Используйте этот метод для блокировки до тех пор, пока WaitHandle не получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.

Переопределите этот метод, чтобы настроить поведение производных классов.

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

Вызов перегрузки этого метода совпадает с вызовом перегрузки WaitOne(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

WaitOne(Int32, Boolean)

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

Блокирует текущий поток до получения сигнала текущим объектом WaitHandle, используя 32-разрядное целое число со знаком для задания периода времени и указывая, следует ли выйти из домена синхронизации до начала ожидания.

C#
public virtual bool WaitOne (int millisecondsTimeout, bool exitContext);

Параметры

millisecondsTimeout
Int32

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

exitContext
Boolean

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

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

Значение true при получении сигнала текущим экземпляром; в противном случае — значение false.

Исключения

Текущий экземпляр уже удален.

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

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

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

Примеры

В следующем примере показано поведение перегрузки WaitOne(Int32, Boolean) метода при вызове в домене синхронизации. Во-первых, поток ожидает с exitContext заданным значением false и блокирует время ожидания, пока не истечет время ожидания. Второй поток выполняется после завершения первого потока и ожидает с exitContext параметром true. Вызов сигнала дескриптора ожидания для этого второго потока не блокируется, и поток завершается до истечения времени ожидания.

C#
using System;
using System.Threading;
using System.Runtime.Remoting.Contexts;

[Synchronization(true)]
public class SyncingClass : ContextBoundObject
{
    private EventWaitHandle waitHandle;

    public SyncingClass()
    {
         waitHandle =
            new EventWaitHandle(false, EventResetMode.ManualReset);
    }

    public void Signal()
    {
        Console.WriteLine("Thread[{0:d4}]: Signalling...", Thread.CurrentThread.GetHashCode());
        waitHandle.Set();
    }

    public void DoWait(bool leaveContext)
    {
        bool signalled;

        waitHandle.Reset();
        Console.WriteLine("Thread[{0:d4}]: Waiting...", Thread.CurrentThread.GetHashCode());
        signalled = waitHandle.WaitOne(3000, leaveContext);
        if (signalled)
        {
            Console.WriteLine("Thread[{0:d4}]: Wait released!!!", Thread.CurrentThread.GetHashCode());
        }
        else
        {
            Console.WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread.CurrentThread.GetHashCode());
        }
    }
}

public class TestSyncDomainWait
{
    public static void Main()
    {
        SyncingClass syncClass = new SyncingClass();

        Thread runWaiter;

        Console.WriteLine("\nWait and signal INSIDE synchronization domain:\n");
        runWaiter = new Thread(RunWaitKeepContext);
        runWaiter.Start(syncClass);
        Thread.Sleep(1000);
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode());
        // This call to Signal will block until the timeout in DoWait expires.
        syncClass.Signal();
        runWaiter.Join();

        Console.WriteLine("\nWait and signal OUTSIDE synchronization domain:\n");
        runWaiter = new Thread(RunWaitLeaveContext);
        runWaiter.Start(syncClass);
        Thread.Sleep(1000);
        Console.WriteLine("Thread[{0:d4}]: Signal...", Thread.CurrentThread.GetHashCode());
        // This call to Signal is unblocked and will set the wait handle to
        // release the waiting thread.
        syncClass.Signal();
        runWaiter.Join();
    }

    public static void RunWaitKeepContext(object parm)
    {
        ((SyncingClass)parm).DoWait(false);
    }

    public static void RunWaitLeaveContext(object parm)
    {
        ((SyncingClass)parm).DoWait(true);
    }
}

// The output for the example program will be similar to the following:
//
// Wait and signal INSIDE synchronization domain:
//
// Thread[0004]: Waiting...
// Thread[0001]: Signal...
// Thread[0004]: Wait timeout!!!
// Thread[0001]: Signalling...
//
// Wait and signal OUTSIDE synchronization domain:
//
// Thread[0006]: Waiting...
// Thread[0001]: Signal...
// Thread[0001]: Signalling...
// Thread[0006]: Wait released!!!

Комментарии

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

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

Вызывающий объект этого метода блокируется до тех пор, пока текущий экземпляр не получит сигнал или не наступает время ожидания. Используйте этот метод для блокировки до тех пор, пока WaitHandle не получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.

Переопределите этот метод, чтобы настроить поведение производных классов.

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

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

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

Выход из контекста может быть полезен, если у класса, связанного с контекстом 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

WaitOne(TimeSpan, Boolean)

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

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

C#
public virtual bool WaitOne (TimeSpan timeout, bool exitContext);

Параметры

timeout
TimeSpan

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

exitContext
Boolean

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

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

Значение true при получении сигнала текущим экземпляром; в противном случае — значение false.

Исключения

Текущий экземпляр уже удален.

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

-или-

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

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

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

Примеры

В следующем примере кода показано, как использовать дескриптор ожидания, чтобы не допустить завершения процесса, пока он ожидает завершения выполнения фонового потока.

C#
using System;
using System.Threading;

class WaitOne
{
    static AutoResetEvent autoEvent = new AutoResetEvent(false);

    static void Main()
    {
        Console.WriteLine("Main starting.");

        ThreadPool.QueueUserWorkItem(
            new WaitCallback(WorkMethod), autoEvent);

        // Wait for work method to signal.
        if(autoEvent.WaitOne(new TimeSpan(0, 0, 1), false))
        {
            Console.WriteLine("Work method signaled.");
        }
        else
        {
            Console.WriteLine("Timed out waiting for work " +
                "method to signal.");
        }
        Console.WriteLine("Main ending.");
    }

    static void WorkMethod(object stateInfo) 
    {
        Console.WriteLine("Work starting.");

        // Simulate time spent working.
        Thread.Sleep(new Random().Next(100, 2000));

        // Signal that work is finished.
        Console.WriteLine("Work ending.");
        ((AutoResetEvent)stateInfo).Set();
    }
}

Комментарии

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

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

Вызывающий объект этого метода блокируется до тех пор, пока текущий экземпляр не получит сигнал или не наступает время ожидания. Используйте этот метод для блокировки до тех пор, пока не WaitHandle получит сигнал из другого потока, например при завершении асинхронной операции. Дополнительные сведения см. в описании интерфейса IAsyncResult.

Переопределите этот метод, чтобы настроить поведение производных классов.

Максимальное значение для 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