Threads onderbreken en onderbreken
De meest voorkomende manieren om de activiteiten van threads te synchroniseren, zijn het blokkeren en vrijgeven van threads, of het vergrendelen van objecten of codegebieden. Zie Overzicht van synchronisatieprimitief voor meer informatie over deze vergrendelings- en blokkeringsmechanismen.
U kunt ook threads in slaap zetten. Wanneer threads worden geblokkeerd of in slaapstand worden geplaatst, kunt u een ThreadInterruptedException thread gebruiken om ze uit hun wachtstatussen te verwijderen.
De thread.Sleep-methode
Als u de Thread.Sleep methode aanroept, wordt de huidige thread onmiddellijk geblokkeerd voor het aantal milliseconden of het tijdsinterval dat u aan de methode doorgeeft, en wordt de rest van het tijdssegment aan een andere thread geretourneerd. Zodra dat interval is verstreken, hervat de slaapthread de uitvoering.
Een thread kan niet worden aangeroepen Thread.Sleep op een andere thread. Thread.Sleep is een statische methode die ervoor zorgt dat de huidige thread altijd in slaapstand wordt gezet.
Als Thread.Sleep een thread met een waarde wordt Timeout.Infinite aangeroepen, wordt een thread in slaapstand gezet totdat deze wordt onderbroken door een andere thread die de Thread.Interrupt methode aanroept op de slaapthread, of totdat deze wordt beƫindigd door een aanroep naar Thread.Abort de methode. In het volgende voorbeeld ziet u beide methoden voor het onderbreken van een slaapthread.
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 '{0}' about to sleep indefinitely.",
Thread.CurrentThread.Name);
try {
Thread.Sleep(Timeout.Infinite);
}
catch (ThreadInterruptedException) {
Console.WriteLine("Thread '{0}' awoken.",
Thread.CurrentThread.Name);
}
catch (ThreadAbortException) {
Console.WriteLine("Thread '{0}' aborted.",
Thread.CurrentThread.Name);
}
finally
{
Console.WriteLine("Thread '{0}' executing finally block.",
Thread.CurrentThread.Name);
}
Console.WriteLine("Thread '{0} finishing normal execution.",
Thread.CurrentThread.Name);
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.
Threads onderbreken
U kunt een wachtthread onderbreken door de Thread.Interrupt methode op de geblokkeerde thread aan te roepen om een ThreadInterruptedException, waardoor de thread uit de blokkeringsoproep wordt verbroken. De thread moet de ThreadInterruptedException thread vangen en doen wat geschikt is om door te gaan met werken. Als de thread de uitzondering negeert, wordt de uitzondering onderschept en wordt de thread gestopt.
Notitie
Als de doelthread niet wordt geblokkeerd wanneer Thread.Interrupt deze wordt aangeroepen, wordt de thread pas onderbroken als deze wordt geblokkeerd. Als de thread nooit wordt geblokkeerd, kan deze worden voltooid zonder ooit te worden onderbroken.
Als een wacht een beheerde wacht is, wordt Thread.Interrupt Thread.Abort de thread onmiddellijk geactiveerd. Als een wachttijd een onbeheerde wachttijd is (bijvoorbeeld een platformaanroep naar de functie Win32 WaitForSingleObject), kan de Thread.Abort thread niet Thread.Interrupt worden beheerd totdat deze wordt teruggeroepen of wordt aangeroepen in beheerde code. In beheerde code is het gedrag als volgt:
Thread.Interrupt ontwaakt een thread uit een wacht die zich mogelijk in en zorgt ervoor dat er een ThreadInterruptedException thread in de doelthread wordt gegenereerd.
Alleen .NET Framework: Thread.Abort hiermee wordt een thread uit een wachttijd geactiveerd en wordt er een ThreadAbortException thread gegenereerd op de thread. Zie Threads vernietigen voor meer informatie.