WaitHandle.WaitOne Metoda

Definicja

Blokuje bieżący wątek, dopóki bieżący WaitHandle nie otrzyma sygnału.

Przeciążenia

WaitOne()

Blokuje bieżący wątek, dopóki bieżący WaitHandle nie otrzyma sygnału.

WaitOne(Int32)

Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu w milisekundach.

WaitOne(TimeSpan)

Blokuje bieżący wątek, dopóki bieżące wystąpienie nie otrzyma sygnału przy użyciu elementu , TimeSpan aby określić interwał czasu.

WaitOne(Int32, Boolean)

Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitOne(TimeSpan, Boolean)

Blokuje bieżący wątek, dopóki bieżące wystąpienie nie otrzyma sygnału, przy użyciu elementu , TimeSpan aby określić interwał czasu i określić, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

WaitOne()

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Blokuje bieżący wątek, dopóki bieżący WaitHandle nie otrzyma sygnału.

public:
 virtual bool WaitOne();
public virtual bool WaitOne ();
abstract member WaitOne : unit -> bool
override this.WaitOne : unit -> bool
Public Overridable Function WaitOne () As Boolean

Zwraca

true jeśli bieżące wystąpienie odbiera sygnał. Jeśli bieżące wystąpienie nigdy nie zostanie zasygnalizowane, WaitOne() nigdy nie zostanie zwrócone.

Wyjątki

Bieżące wystąpienie zostało już usunięte.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Bieżące wystąpienie jest przezroczystym serwerem proxy dla WaitHandle innej domeny aplikacji.

Przykłady

W poniższym przykładzie kodu pokazano, jak użyć uchwytu oczekiwania, aby zatrzymać proces podczas oczekiwania na zakończenie wykonywania wątku w tle.

using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
   WaitOne(){}


public:
   static void WorkMethod( Object^ stateInfo )
   {
      Console::WriteLine( "Work starting." );
      
      // Simulate time spent working.
      Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
      
      // Signal that work is finished.
      Console::WriteLine( "Work ending." );
      dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
   }

};

int main()
{
   Console::WriteLine( "Main starting." );
   AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
   ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
   
   // Wait for work method to signal.
   autoEvent->WaitOne(  );
   Console::WriteLine( "Work method signaled.\nMain ending." );
}
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();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        autoEvent.WaitOne()
        Console.WriteLine("Work method signaled.")
        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Uwagi

AbandonedMutexExceptionjest nowy w wersji .NET Framework 2.0. W poprzednich wersjach metoda zwraca wartość true po WaitOne porzuceniu mutexu. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.

Obiekt wywołujący tej metody blokuje bezterminowo, dopóki bieżące wystąpienie nie otrzyma sygnału. Użyj tej metody, aby zablokować, dopóki WaitHandle sygnał z innego wątku nie zostanie wygenerowany, na przykład po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.

Wywołanie tego przeciążenia metody jest równoważne wywołaniu WaitOne(Int32, Boolean) przeciążenia metody i określeniu -1 lub Timeout.Infinite dla pierwszego parametru i false drugiego parametru.

Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.

Dotyczy

WaitOne(Int32)

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu w milisekundach.

public:
 virtual bool WaitOne(int millisecondsTimeout);
public virtual bool WaitOne (int millisecondsTimeout);
abstract member WaitOne : int -> bool
override this.WaitOne : int -> bool
Public Overridable Function WaitOne (millisecondsTimeout As Integer) As Boolean

Parametry

millisecondsTimeout
Int32

Liczba milisekund oczekiwania lub Infinite (-1) na czas nieokreślony.

Zwraca

true jeśli bieżące wystąpienie odbiera sygnał; w przeciwnym razie , false.

Wyjątki

Bieżące wystąpienie zostało już usunięte.

millisecondsTimeout jest liczbą ujemną inną niż -1, która reprezentuje nieskończony limit czasu.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Bieżące wystąpienie jest przezroczystym serwerem proxy dla WaitHandle innej domeny aplikacji.

Przykłady

W poniższym przykładzie kodu pokazano, jak użyć uchwytu oczekiwania, aby zatrzymać proces podczas oczekiwania na zakończenie wykonywania wątku w tle.

using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
   WaitOne(){}


public:
   static void WorkMethod( Object^ stateInfo )
   {
      Console::WriteLine( "Work starting." );
      
      // Simulate time spent working.
      Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
      
      // Signal that work is finished.
      Console::WriteLine( "Work ending." );
      dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
   }

};

int main()
{
   Console::WriteLine( "Main starting." );
   AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
   ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::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." );
}
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();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        If autoEvent.WaitOne(1000) Then
            Console.WriteLine("Work method signaled.")
        Else
            Console.WriteLine("Timed out waiting for work " & _
                "method to signal.")
        End If

        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Uwagi

Jeśli millisecondsTimeout jest zero, metoda nie blokuje. Testuje stan uchwytu oczekiwania i zwraca natychmiast.

Obiekt wywołujący tej metody blokuje, dopóki bieżące wystąpienie nie otrzyma sygnału lub przekroczenia limitu czasu. Użyj tej metody, aby zablokować, dopóki WaitHandle sygnał z innego wątku nie zostanie wygenerowany, na przykład po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.

Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.

Wywoływanie tego przeciążenia metody jest takie samo, jak wywoływanie WaitOne(Int32, Boolean) przeciążenia i określanie false wartości .exitContext

Dotyczy

WaitOne(TimeSpan)

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Blokuje bieżący wątek, dopóki bieżące wystąpienie nie otrzyma sygnału przy użyciu elementu , TimeSpan aby określić interwał czasu.

public:
 virtual bool WaitOne(TimeSpan timeout);
public virtual bool WaitOne (TimeSpan timeout);
abstract member WaitOne : TimeSpan -> bool
override this.WaitOne : TimeSpan -> bool
Public Overridable Function WaitOne (timeout As TimeSpan) As Boolean

Parametry

timeout
TimeSpan

Element TimeSpan reprezentujący liczbę milisekund oczekiwania lub wartość reprezentującą TimeSpan -1 milisekundy oczekiwania na czas nieokreślony.

Zwraca

true jeśli bieżące wystąpienie odbiera sygnał; w przeciwnym razie , false.

Wyjątki

Bieżące wystąpienie zostało już usunięte.

timeout jest liczbą ujemną inną niż -1 milisekund, która reprezentuje nieskończony limit czasu.

-lub-

timeout wartość jest większa niż Int32.MaxValue.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Bieżące wystąpienie jest przezroczystym serwerem proxy dla WaitHandle innej domeny aplikacji.

Uwagi

Jeśli timeout jest zero, metoda nie blokuje. Testuje stan uchwytu oczekiwania i zwraca natychmiast.

Obiekt wywołujący tej metody blokuje, dopóki bieżące wystąpienie nie otrzyma sygnału lub przekroczenia limitu czasu. Użyj tej metody, aby zablokować, dopóki WaitHandle sygnał z innego wątku nie zostanie wygenerowany, na przykład po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.

Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.

Wartość maksymalna to timeoutInt32.MaxValue.

Wywoływanie tego przeciążenia metody jest takie samo, jak wywoływanie WaitOne(TimeSpan, Boolean) przeciążenia i określanie false wartości .exitContext

Dotyczy

WaitOne(Int32, Boolean)

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Blokuje bieżący wątek do WaitHandle momentu odebrania sygnału przy użyciu 32-bitowej liczby całkowitej podpisanej w celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

public:
 virtual bool WaitOne(int millisecondsTimeout, bool exitContext);
public virtual bool WaitOne (int millisecondsTimeout, bool exitContext);
abstract member WaitOne : int * bool -> bool
override this.WaitOne : int * bool -> bool
Public Overridable Function WaitOne (millisecondsTimeout As Integer, exitContext As Boolean) As Boolean

Parametry

millisecondsTimeout
Int32

Liczba milisekund oczekiwania lub Infinite (-1) na czas nieokreślony.

exitContext
Boolean

true aby zamknąć domenę synchronizacji dla kontekstu przed oczekiwaniem (jeśli w zsynchronizowanym kontekście) i ponownie go później; w przeciwnym razie , false.

Zwraca

true jeśli bieżące wystąpienie odbiera sygnał; w przeciwnym razie , false.

Wyjątki

Bieżące wystąpienie zostało już usunięte.

millisecondsTimeout jest liczbą ujemną inną niż -1, która reprezentuje nieskończony limit czasu.

Oczekiwanie zostało zakończone, ponieważ wątek zakończył się bez zwalniania mutexu.

Bieżące wystąpienie jest przezroczystym serwerem proxy dla WaitHandle innej domeny aplikacji.

Przykłady

W poniższym przykładzie pokazano, jak WaitOne(Int32, Boolean) przeciążenie metody działa, gdy jest wywoływane w domenie synchronizacji. Najpierw wątek czeka z ustawioną wartością exitContextfalse i blokuje do momentu wygaśnięcia limitu czasu oczekiwania. Drugi wątek jest wykonywany po zakończeniu pierwszego wątku i oczekiwaniu z ustawionym exitContext na truewartość . Wywołanie sygnalizatora oczekiwania dla tego drugiego wątku nie jest zablokowane, a wątek zostanie zakończony przed przekroczeniem limitu czasu oczekiwania.

using namespace System;
using namespace System::Threading;
using namespace System::Runtime::Remoting::Contexts;

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

public:
    SyncingClass()
    {
         waitHandle =
            gcnew EventWaitHandle(false, EventResetMode::ManualReset);
    }

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

    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 ref class TestSyncDomainWait
{
public:
    static void Main()
    {
        SyncingClass^ syncClass = gcnew SyncingClass();

        Thread^ runWaiter;

        Console::WriteLine("\nWait and signal INSIDE synchronization domain:\n");
        runWaiter = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::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 = gcnew Thread(gcnew ParameterizedThreadStart(&TestSyncDomainWait::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();
    }

    static void RunWaitKeepContext(Object^ parm)
    {
        ((SyncingClass^)parm)->DoWait(false);
    }

    static void RunWaitLeaveContext(Object^ parm)
    {
        ((SyncingClass^)parm)->DoWait(true);
    }
};

int main()
{
    TestSyncDomainWait::Main();
}
// 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!!!
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!!!
Imports System.Threading
Imports System.Runtime.Remoting.Contexts

<Synchronization(true)>
Public Class SyncingClass
    Inherits ContextBoundObject
    
    Private waitHandle As EventWaitHandle

    Public Sub New()
         waitHandle = New EventWaitHandle(false, EventResetMode.ManualReset)
    End Sub

    Public Sub Signal()
        Console.WriteLine("Thread[{0:d4}]: Signalling...", Thread.CurrentThread.GetHashCode())
        waitHandle.Set()
    End Sub

    Public Sub DoWait(leaveContext As Boolean)
        Dim signalled As Boolean

        waitHandle.Reset()
        Console.WriteLine("Thread[{0:d4}]: Waiting...", Thread.CurrentThread.GetHashCode())
        signalled = waitHandle.WaitOne(3000, leaveContext)
        If signalled Then
            Console.WriteLine("Thread[{0:d4}]: Wait released!!!", Thread.CurrentThread.GetHashCode())
        Else
            Console.WriteLine("Thread[{0:d4}]: Wait timeout!!!", Thread.CurrentThread.GetHashCode())
        End If
    End Sub
End Class

Public Class TestSyncDomainWait
    Public Shared Sub Main()
        Dim syncClass As New SyncingClass()

        Dim runWaiter As Thread

        Console.WriteLine(Environment.NewLine + "Wait and signal INSIDE synchronization domain:" + Environment.NewLine)
        runWaiter = New Thread(AddressOf 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(Environment.NewLine + "Wait and signal OUTSIDE synchronization domain:" + Environment.NewLine)
        runWaiter = New Thread(AddressOf 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()
    End Sub

    Public Shared Sub RunWaitKeepContext(parm As Object)
        Dim syncClass As SyncingClass = CType(parm, SyncingClass)
        syncClass.DoWait(False)
    End Sub

    Public Shared Sub RunWaitLeaveContext(parm As Object)
        Dim syncClass As SyncingClass = CType(parm, SyncingClass)
        syncClass.DoWait(True)
    End Sub
End Class

' 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!!!

Uwagi

Jeśli millisecondsTimeout jest zero, metoda nie blokuje. Testuje stan uchwytu oczekiwania i zwraca natychmiast.

Jeśli mutex zostanie porzucony, AbandonedMutexException zostanie zgłoszony. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku mutexu całego systemu może to oznaczać, że aplikacja została nagle zakończona (na przykład przy użyciu Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.

Obiekt wywołujący tej metody blokuje, dopóki bieżące wystąpienie nie otrzyma sygnału lub przekroczenia limitu czasu. Użyj tej metody, aby zablokować, dopóki WaitHandle sygnał z innego wątku nie zostanie wygenerowany, na przykład po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.

Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.

Zamykanie kontekstu

Parametr exitContext nie ma wpływu, chyba że ta metoda jest wywoływana z wewnątrz kontekstu zarządzanego niezdefault. Kontekst zarządzany może być niezdefault, jeśli wątek znajduje się wewnątrz wywołania wystąpienia klasy pochodzącej z ContextBoundObjectklasy . Nawet jeśli obecnie wykonujesz metodę w klasie, która nie pochodzi z ContextBoundObjectklasy , na przykład String, możesz być w kontekście niezdefault, jeśli element ContextBoundObject znajduje się na stosie w bieżącej domenie aplikacji.

Gdy kod jest wykonywany w kontekście niezdefinicyjnym, określając true przyczynę exitContext zakończenia kontekstu zarządzanego niezdefault (czyli przejścia do kontekstu domyślnego) przed wykonaniem tej metody. Wątek powraca do oryginalnego kontekstu niezdefault po zakończeniu wywołania tej metody.

Zamknięcie kontekstu może być przydatne, gdy klasa powiązana z kontekstem SynchronizationAttribute ma atrybut . W takim przypadku wszystkie wywołania do składowych klasy są automatycznie synchronizowane, a domena synchronizacji to cała treść kodu dla klasy. Jeśli kod w stosie wywołań elementu członkowskiego wywołuje tę metodę i określa true dla exitContextelementu , wątek zamyka domenę synchronizacji, co umożliwia wątkowi zablokowanemu wywołanie do dowolnego elementu członkowskiego obiektu. Gdy ta metoda zostanie zwrócona, wątek, który wykonał wywołanie, musi poczekać na ponowne włączenie domeny synchronizacji.

Dotyczy

WaitOne(TimeSpan, Boolean)

Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs
Źródło:
WaitHandle.cs

Blokuje bieżący wątek do momentu odebrania sygnału przez bieżące wystąpienie przy użyciu parametru w TimeSpan celu określenia interwału czasu i określenia, czy należy zamknąć domenę synchronizacji przed oczekiwaniem.

public:
 virtual bool WaitOne(TimeSpan timeout, bool exitContext);
public virtual bool WaitOne (TimeSpan timeout, bool exitContext);
abstract member WaitOne : TimeSpan * bool -> bool
override this.WaitOne : TimeSpan * bool -> bool
Public Overridable Function WaitOne (timeout As TimeSpan, exitContext As Boolean) As Boolean

Parametry

timeout
TimeSpan

Wartość TimeSpan reprezentująca liczbę milisekund oczekiwania lub wartość reprezentująca TimeSpan -1 milisekundy oczekiwania na czas nieokreślony.

exitContext
Boolean

true aby zamknąć domenę synchronizacji dla kontekstu przed oczekiwaniem (jeśli w zsynchronizowanym kontekście) i ponownie go później; w przeciwnym razie , false.

Zwraca

true jeśli bieżące wystąpienie odbiera sygnał; w przeciwnym razie , false.

Wyjątki

Bieżące wystąpienie zostało już usunięte.

timeout jest liczbą ujemną inną niż -1 milisekund, która reprezentuje nieskończony limit czasu.

-lub-

timeout wartość jest większa niż Int32.MaxValue.

Oczekiwanie zostało ukończone, ponieważ wątek zakończył się bez zwolnienia mutexu.

Bieżące wystąpienie jest przezroczystym serwerem proxy dla domeny WaitHandle w innej domenie aplikacji.

Przykłady

W poniższym przykładzie kodu pokazano, jak użyć uchwytu oczekiwania, aby zatrzymać proces podczas oczekiwania na zakończenie wykonywania wątku w tle.

using namespace System;
using namespace System::Threading;
ref class WaitOne
{
private:
   WaitOne(){}


public:
   static void WorkMethod( Object^ stateInfo )
   {
      Console::WriteLine( "Work starting." );
      
      // Simulate time spent working.
      Thread::Sleep( (gcnew Random)->Next( 100, 2000 ) );
      
      // Signal that work is finished.
      Console::WriteLine( "Work ending." );
      dynamic_cast<AutoResetEvent^>(stateInfo)->Set();
   }

};

int main()
{
   Console::WriteLine( "Main starting." );
   AutoResetEvent^ autoEvent = gcnew AutoResetEvent( false );
   ThreadPool::QueueUserWorkItem( gcnew WaitCallback( &WaitOne::WorkMethod ), autoEvent );
   
   // Wait for work method to signal.
   if ( autoEvent->WaitOne( 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." );
}
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();
    }
}
Imports System.Threading

Public Class WaitOne

    Shared autoEvent As New AutoResetEvent(False)

    <MTAThread> _
    Shared Sub Main()
        Console.WriteLine("Main starting.")

        ThreadPool.QueueUserWorkItem(AddressOf WorkMethod, autoEvent)

        ' Wait for work method to signal.
        If autoEvent.WaitOne(New TimeSpan(0, 0, 1), False) Then
            Console.WriteLine("Work method signaled.")
        Else
            Console.WriteLine("Timed out waiting for work " & _
                "method to signal.")
        End If

        Console.WriteLine("Main ending.")
    End Sub

    Shared Sub WorkMethod(stateInfo As Object) 
        Console.WriteLine("Work starting.")

        ' Simulate time spent working.
        Thread.Sleep(New Random().Next(100, 2000))

        ' Signal that work is finished.
        Console.WriteLine("Work ending.")
        CType(stateInfo, AutoResetEvent).Set()
    End Sub

End Class

Uwagi

Jeśli timeout wartość jest równa zero, metoda nie blokuje. Testuje stan dojścia oczekiwania i zwraca natychmiast.

Jeśli mutex zostanie porzucony, AbandonedMutexException jest zgłaszany. Porzucony mutex często wskazuje poważny błąd kodowania. W przypadku całego systemu mutex może wskazywać, że aplikacja została nagle zakończona (na przykład za pomocą Menedżera zadań systemu Windows). Wyjątek zawiera informacje przydatne do debugowania.

Obiekt wywołujący tej metody blokuje, dopóki bieżące wystąpienie nie odbierze sygnału lub upłynął limit czasu. Ta metoda służy do blokowania do momentu WaitHandle odebrania sygnału z innego wątku, takiego jak jest generowany po zakończeniu operacji asynchronicznej. Aby uzyskać więcej informacji, zobacz IAsyncResult interfejs.

Zastąp tę metodę, aby dostosować zachowanie klas pochodnych.

Wartość maksymalna dla parametru timeout to Int32.MaxValue.

Zamykanie kontekstu

Parametr exitContext nie ma wpływu, chyba że ta metoda jest wywoływana z wewnątrz kontekstu zarządzanego bez definicji. Kontekst zarządzany może być niezdefault, jeśli wątek znajduje się wewnątrz wywołania do wystąpienia klasy pochodzącej z ContextBoundObjectklasy . Nawet jeśli obecnie wykonujesz metodę w klasie, która nie pochodzi z ContextBoundObjectklasy , na przykład String, możesz znajdować się w kontekście niedefault, jeśli element ContextBoundObject znajduje się na stosie w bieżącej domenie aplikacji.

Gdy kod jest wykonywany w kontekście niedefault, określając true , że exitContext wątek ma zamknąć niedefaultowy kontekst zarządzany (tj. przejść do kontekstu domyślnego) przed wykonaniem tej metody. Po zakończeniu wywołania tej metody wątek powraca do oryginalnego kontekstu niezdefaultowego.

Zamknięcie kontekstu może być przydatne, gdy klasa powiązana kontekstem SynchronizationAttribute ma atrybut . W takim przypadku wszystkie wywołania elementów członkowskich klasy są automatycznie synchronizowane, a domena synchronizacji jest całą treścią kodu dla klasy. Jeśli kod w stosie wywołań elementu członkowskiego wywołuje tę metodę i określa true metodę exitContext, wątek kończy domenę synchronizacji, co umożliwia kontynuowanie wątku, który jest blokowany w wywołaniu dowolnego elementu członkowskiego obiektu. Gdy ta metoda powróci, wątek, który wykonał wywołanie, musi poczekać na ponowne włączenie domeny synchronizacji.

Dotyczy