Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
I modi più comuni per sincronizzare le attività dei thread sono bloccare e rilasciare thread o bloccare oggetti o aree di codice. Per ulteriori informazioni su questi meccanismi di locking e blocco, vedere Panoramica delle primitive di sincronizzazione.
È anche possibile fare in modo che i thread si addormentino. Quando i thread vengono bloccati o sono in stato di sospensione, è possibile usare un ThreadInterruptedException per sbloccarli dai loro stati di attesa.
Metodo Thread.Sleep
La chiamata al Thread.Sleep metodo fa sì che il thread corrente blocchi immediatamente per il numero di millisecondi o l'intervallo di tempo passato al metodo e restituisce il resto della sezione temporale a un altro thread. Una volta trascorso l'intervallo, il thread in sospensione riprende l'esecuzione.
Un thread non può chiamare Thread.Sleep su un altro thread. Thread.Sleep è un metodo statico che determina sempre la sospensione del thread corrente.
La chiamata Thread.Sleep con un valore di Timeout.Infinite fa sì che un thread venga sospeso fino a quando non viene interrotto da un altro thread che chiama il Thread.Interrupt metodo sul thread in sospensione o fino a quando non viene terminato da una chiamata al relativo Thread.Abort metodo. Nell'esempio seguente vengono illustrati entrambi i metodi di interruzione di un thread in sospensione.
using System;
using System.Threading;
public class Example
{
public static void Main()
{
// Interrupt a sleeping thread.
var sleepingThread = new Thread(Example.SleepIndefinitely);
sleepingThread.Name = "Sleeping";
sleepingThread.Start();
Thread.Sleep(2000);
sleepingThread.Interrupt();
Thread.Sleep(1000);
sleepingThread = new Thread(Example.SleepIndefinitely);
sleepingThread.Name = "Sleeping2";
sleepingThread.Start();
Thread.Sleep(2000);
sleepingThread.Abort();
}
private static void SleepIndefinitely()
{
Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' about to sleep indefinitely.");
try {
Thread.Sleep(Timeout.Infinite);
}
catch (ThreadInterruptedException) {
Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' awoken.");
}
catch (ThreadAbortException) {
Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' aborted.");
}
finally
{
Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' executing finally block.");
}
Console.WriteLine($"Thread '{Thread.CurrentThread.Name} finishing normal execution.");
Console.WriteLine();
}
}
// The example displays the following output:
// Thread 'Sleeping' about to sleep indefinitely.
// Thread 'Sleeping' awoken.
// Thread 'Sleeping' executing finally block.
// Thread 'Sleeping finishing normal execution.
//
// Thread 'Sleeping2' about to sleep indefinitely.
// Thread 'Sleeping2' aborted.
// Thread 'Sleeping2' executing finally block.
Imports System.Threading
Module Example
Public Sub Main()
' Interrupt a sleeping thread.
Dim sleepingThread = New Thread(AddressOf Example.SleepIndefinitely)
sleepingThread.Name = "Sleeping"
sleepingThread.Start()
Thread.Sleep(2000)
sleepingThread.Interrupt()
Thread.Sleep(1000)
sleepingThread = New Thread(AddressOf Example.SleepIndefinitely)
sleepingThread.Name = "Sleeping2"
sleepingThread.Start()
Thread.Sleep(2000)
sleepingThread.Abort()
End Sub
Private Sub SleepIndefinitely()
Console.WriteLine("Thread '{0}' about to sleep indefinitely.",
Thread.CurrentThread.Name)
Try
Thread.Sleep(Timeout.Infinite)
Catch ex As ThreadInterruptedException
Console.WriteLine("Thread '{0}' awoken.",
Thread.CurrentThread.Name)
Catch ex As ThreadAbortException
Console.WriteLine("Thread '{0}' aborted.",
Thread.CurrentThread.Name)
Finally
Console.WriteLine("Thread '{0}' executing finally block.",
Thread.CurrentThread.Name)
End Try
Console.WriteLine("Thread '{0}' finishing normal execution.",
Thread.CurrentThread.Name)
Console.WriteLine()
End Sub
End Module
' The example displays the following output:
' Thread 'Sleeping' about to sleep indefinitely.
' Thread 'Sleeping' awoken.
' Thread 'Sleeping' executing finally block.
' Thread 'Sleeping finishing normal execution.
'
' Thread 'Sleeping2' about to sleep indefinitely.
' Thread 'Sleeping2' aborted.
' Thread 'Sleeping2' executing finally block.
Interruzione dei thread
È possibile interrompere un thread in attesa chiamando il metodo Thread.Interrupt sul thread bloccato per generare un oggetto ThreadInterruptedException, che consente al thread di uscire dalla chiamata di blocco. Il thread deve intercettare ThreadInterruptedException e eseguire qualsiasi operazione appropriata per continuare a funzionare. Se il thread ignora l'eccezione, il runtime intercetta l'eccezione e arresta il thread.
Nota
Se il thread di destinazione non viene bloccato quando Thread.Interrupt viene chiamato, il thread non viene interrotto fino a quando non si blocca. Se il thread non si blocca mai, potrebbe essere completato senza mai essere interrotto.
Se un'attesa è un'attesa gestita, allora sia Thread.Interrupt che Thread.Abort riattivano immediatamente il thread. Se un'attesa è un'attesa non gestita (ad esempio, una chiamata platform invoke alla funzione Win32 WaitForSingleObject ), né Thread.Interrupt né Thread.Abort possono assumere il controllo del thread fino a quando non ritorna o non chiama nel codice gestito. Nel codice gestito il comportamento è il seguente:
Thread.Interrupt riattiva un thread da qualunque stato di attesa in cui possa trovarsi e provoca il lancio di un'eccezione ThreadInterruptedException nel thread di destinazione.
Solo .NET Framework: Thread.Abort risveglia un thread da qualsiasi stato di attesa in cui si trovi e causa un'eccezione ThreadAbortException sul thread. Per informazioni dettagliate, vedere Eliminare i thread.