Delen via


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:

Zie ook