Condividi tramite


WaitHandle.WaitOne Metodo

Definizione

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale.

Overload

WaitOne()

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale.

WaitOne(Int32)

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo.

WaitOne(TimeSpan)

Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

WaitOne(Int32, Boolean)

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitOne(TimeSpan, Boolean)

Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un oggetto TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

WaitOne()

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale.

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

Restituisce

Viene restituito true se l'istanza corrente riceve un segnale. Se l'istanza corrente non viene mai segnalata, WaitOne() non restituisce mai alcun valore.

Eccezioni

L'istanza corrente è già stata eliminata.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.

Esempio

Nell'esempio di codice seguente viene illustrato come usare un handle di attesa per impedire a un processo di terminazione mentre attende che un thread in background finisca l'esecuzione.

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

Commenti

AbandonedMutexException è nuovo in .NET Framework versione 2.0. Nelle versioni precedenti, il WaitOne metodo restituisce true quando viene abbandonato un mutex. Un mutex abbandonato spesso indica un grave errore di codifica. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente (ad esempio usando Gestione attività di Windows). L'eccezione contiene informazioni utili per il debug.

Il chiamante di questo metodo blocca indefinito fino a quando l'istanza corrente riceve un segnale. Usare questo metodo per bloccare finché un WaitHandle segnale non riceve un segnale da un altro thread, ad esempio viene generato al termine di un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .

La chiamata all'overload di questo metodo equivale a chiamare l'overload del WaitOne(Int32, Boolean) metodo e specificare -1 o Timeout.Infinite per il primo parametro e false per il secondo parametro.

Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.

Si applica a

WaitOne(Int32)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo.

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

Parametri

millisecondsTimeout
Int32

Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.

Restituisce

true se l'istanza corrente riceve un segnale; in caso contrario false.

Eccezioni

L'istanza corrente è già stata eliminata.

millisecondsTimeout è un numero negativo diverso da -1, che rappresenta un timeout infinito.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.

Esempio

Nell'esempio di codice seguente viene illustrato come usare un handle di attesa per impedire a un processo di terminazione mentre attende che un thread in background finisca l'esecuzione.

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

Commenti

Se millisecondsTimeout è zero, il metodo non blocca. Verifica lo stato dell'handle di attesa e restituisce immediatamente.

Il chiamante di questo metodo blocca fino a quando l'istanza corrente riceve un segnale o un timeout. Usare questo metodo per bloccare finché un WaitHandle segnale non riceve un segnale da un altro thread, ad esempio viene generato al termine di un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .

Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.

La chiamata all'overload di questo metodo è uguale a quella di chiamare l'overload WaitOne(Int32, Boolean) e specificare false per exitContext.

Si applica a

WaitOne(TimeSpan)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un valore TimeSpan per specificare l'intervallo di tempo.

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

Parametri

timeout
TimeSpan

Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.

Restituisce

true se l'istanza corrente riceve un segnale; in caso contrario false.

Eccezioni

L'istanza corrente è già stata eliminata.

timeout è un numero negativo diverso da -1 millisecondi, che rappresenta un timeout infinito.

-oppure-

timeout è maggiore di Int32.MaxValue.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.

Commenti

Se timeout è zero, il metodo non blocca. Verifica lo stato dell'handle di attesa e restituisce immediatamente.

Il chiamante di questo metodo blocca fino a quando l'istanza corrente riceve un segnale o un timeout. Usare questo metodo per bloccare finché un WaitHandle segnale non riceve un segnale da un altro thread, ad esempio viene generato al termine di un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .

Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.

Il valore massimo per timeout è Int32.MaxValue.

La chiamata all'overload di questo metodo è uguale a quella di chiamare l'overload WaitOne(TimeSpan, Boolean) e specificare false per exitContext.

Si applica a

WaitOne(Int32, Boolean)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Blocca il thread corrente finché l'oggetto WaitHandle corrente non riceve un segnale, usando un intero con segno a 32 bit per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

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

Parametri

millisecondsTimeout
Int32

Numero di millisecondi di attesa oppure Infinite (-1) per un'attesa indefinita.

exitContext
Boolean

true per uscire dal dominio di sincronizzazione per il contesto prima dell'attesa, se all'interno di un contesto sincronizzato, e riacquisirlo successivamente; in caso contrario, false.

Restituisce

true se l'istanza corrente riceve un segnale; in caso contrario false.

Eccezioni

L'istanza corrente è già stata eliminata.

millisecondsTimeout è un numero negativo diverso da -1, che rappresenta un timeout infinito.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.

Esempio

Nell'esempio seguente viene illustrato il comportamento dell'overload del WaitOne(Int32, Boolean) metodo quando viene chiamato all'interno di un dominio di sincronizzazione. Prima di tutto, un thread attende con exitContext impostato su false e blocca fino alla scadenza del timeout di attesa. Un secondo thread viene eseguito dopo che il primo thread termina e attende con exitContext impostato su true. La chiamata per segnalare l'handle di attesa per questo secondo thread non è bloccata e il thread viene completato prima del timeout di attesa.

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

Commenti

Se millisecondsTimeout è zero, il metodo non blocca. Verifica lo stato dell'handle di attesa e restituisce immediatamente.

Se viene abbandonato un mutex, viene generato un AbandonedMutexException oggetto. Un mutex abbandonato spesso indica un grave errore di codifica. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente (ad esempio usando Gestione attività di Windows). L'eccezione contiene informazioni utili per il debug.

Il chiamante di questo metodo blocca fino a quando l'istanza corrente riceve un segnale o un timeout. Usare questo metodo per bloccare finché un WaitHandle segnale non riceve un segnale da un altro thread, ad esempio viene generato al termine di un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .

Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.

Uscita dal contesto

Il exitContext parametro non ha alcun effetto a meno che questo metodo non venga chiamato dall'interno di un contesto gestito non definito. Il contesto gestito può essere non definito se il thread si trova all'interno di una chiamata a un'istanza di una classe derivata da ContextBoundObject. Anche se si sta eseguendo un metodo in una classe che non è derivata da ContextBoundObject, ad esempio String, è possibile essere in un contesto non definito se un ContextBoundObject è nello stack nel dominio dell'applicazione corrente.

Quando il codice viene eseguito in un contesto non definito, specificando true per exitContext causare l'uscita del thread dal contesto gestito non definito, ovvero per passare al contesto predefinito, prima di eseguire questo metodo. Il thread torna al contesto non definito originale dopo il completamento della chiamata a questo metodo.

L'uscita dal contesto può essere utile quando la classe associata al contesto ha l'attributo SynchronizationAttribute . In tal caso, tutte le chiamate ai membri della classe vengono sincronizzate automaticamente e il dominio di sincronizzazione è l'intero corpo del codice per la classe. Se il codice nello stack di chiamate di un membro chiama questo metodo e specifica true per exitContext, il thread chiude il dominio di sincronizzazione, che consente a un thread bloccato su una chiamata a qualsiasi membro dell'oggetto di procedere. Quando questo metodo restituisce, il thread che ha effettuato la chiamata deve attendere di tornare al dominio di sincronizzazione.

Si applica a

WaitOne(TimeSpan, Boolean)

Origine:
WaitHandle.cs
Origine:
WaitHandle.cs
Origine:
WaitHandle.cs

Blocca il thread corrente finché l'istanza corrente non riceve un segnale, usando un oggetto TimeSpan per specificare l'intervallo di tempo e indicando se uscire dal dominio di sincronizzazione prima dell'attesa.

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

Parametri

timeout
TimeSpan

Oggetto TimeSpan che rappresenta il numero di millisecondi di attesa oppure TimeSpan che rappresenta -1 millisecondi per un'attesa indefinita.

exitContext
Boolean

true per uscire dal dominio di sincronizzazione per il contesto prima dell'attesa, se all'interno di un contesto sincronizzato, e riacquisirlo successivamente; in caso contrario, false.

Restituisce

true se l'istanza corrente riceve un segnale; in caso contrario false.

Eccezioni

L'istanza corrente è già stata eliminata.

timeout è un numero negativo diverso da -1 millisecondi, che rappresenta un timeout infinito.

-oppure-

timeout è maggiore di Int32.MaxValue.

L'attesa è terminata perché un thread è stato chiuso senza rilasciare un mutex.

L'istanza corrente corrisponde a un proxy trasparente per una classe WaitHandle in un altro dominio applicazione.

Esempio

Nell'esempio di codice seguente viene illustrato come usare un handle di attesa per impedire a un processo di terminazione mentre attende che un thread in background finisca l'esecuzione.

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

Commenti

Se timeout è zero, il metodo non viene bloccato. Verifica lo stato dell'handle di attesa e restituisce immediatamente.

Se un mutex viene abbandonato, viene generata un'eccezione AbandonedMutexException . Un mutex abbandonato spesso indica un errore di codifica grave. Nel caso di un mutex a livello di sistema, potrebbe indicare che un'applicazione è stata terminata bruscamente ,ad esempio tramite Gestione attività di Windows. L'eccezione contiene informazioni utili per il debug.

Il chiamante di questo metodo si blocca finché l'istanza corrente non riceve un segnale o si verifica un timeout. Usare questo metodo per bloccare finché un oggetto WaitHandle non riceve un segnale da un altro thread, ad esempio quando viene completata un'operazione asincrona. Per altre informazioni, vedere l'interfaccia IAsyncResult .

Eseguire l'override di questo metodo per personalizzare il comportamento delle classi derivate.

Il valore massimo per timeout è Int32.MaxValue.

Uscita dal contesto

Il exitContext parametro non ha alcun effetto a meno che questo metodo non venga chiamato dall'interno di un contesto gestito non predefinito. Il contesto gestito può essere non predefinito se il thread si trova all'interno di una chiamata a un'istanza di una classe derivata da ContextBoundObject. Anche se attualmente si esegue un metodo in una classe che non è derivata da ContextBoundObject, ad esempio String, è possibile trovarsi in un contesto non predefinito se un ContextBoundObject oggetto si trova nello stack nel dominio applicazione corrente.

Quando il codice viene eseguito in un contesto non predefinito, se true si specifica per exitContext fa in modo che il thread esce dal contesto gestito non predefinito, ovvero per passare al contesto predefinito, prima di eseguire questo metodo. Il thread torna al contesto non predefinito originale al termine della chiamata a questo metodo.

L'uscita dal contesto può essere utile quando la classe associata al contesto ha l'attributo SynchronizationAttribute . In tal caso, tutte le chiamate ai membri della classe vengono sincronizzate automaticamente e il dominio di sincronizzazione è l'intero corpo del codice per la classe . Se il codice nello stack di chiamate di un membro chiama questo metodo e specifica true per exitContext, il thread esce dal dominio di sincronizzazione, che consente a un thread bloccato in una chiamata a qualsiasi membro dell'oggetto di continuare. Quando termina, il thread che ha eseguito la chiamata deve attendere di immettere nuovamente il dominio di sincronizzazione.

Si applica a