Freigeben über


Anhalten und Unterbrechen von Threads

Die gängigsten Methoden zum Synchronisieren der Aktivitäten von Threads sind das Blockieren und Freigeben von Threads oder das Sperren von Objekten oder Codebereichen. Weitere Informationen zu diesen Sperr- und Blockierungsmechanismen finden Sie unter Übersicht über Synchronisierungsgrundtypen.

Sie können auch Threads in den Ruhezustand versetzen. Wenn Threads blockiert sind oder sich im Ruhezustand befinden, können Sie mit einem ThreadInterruptedException ihren Wartezustand beenden.

Thread.Sleep-Methode

Wenn Sie die Thread.Sleep Methode aufrufen, wird der aktuelle Thread sofort für die Anzahl von Millisekunden oder das Zeitintervall blockiert, das Sie an die Methode übergeben, und gibt den Rest des Zeitsegments für einen anderen Thread zurück. Sobald dieses Intervall verstrichen ist, setzt der wartende Thread die Ausführung fort.

Ein Thread kann Thread.Sleep nicht in einem anderen Thread aufrufen. Thread.Sleep ist eine statische Methode, die immer bewirkt, dass der aktuelle Thread in den Ruhezustand wechselt.

Das Aufrufen Thread.Sleep mit einem Wert Timeout.Infinite bewirkt, dass ein Thread in den Ruhezustand wechselt, bis ein anderer Thread die Thread.Interrupt Methode für den schlafenden Thread aufruft. Im folgenden Beispiel wird veranschaulicht, wie ein Schlafthread unterbrochen wird.

using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // Interrupt a sleeping thread.
        var sleepingThread = new Thread(SleepIndefinitely);
        sleepingThread.Name = "Sleeping";
        sleepingThread.Start();
        Thread.Sleep(2000);
        sleepingThread.Interrupt();
        sleepingThread.Join();
    }

    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.");
        }
        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.
Imports System.Threading

Module Example
    Public Sub Main()
        ' Interrupt a sleeping thread.
        Dim sleepingThread = New Thread(AddressOf SleepIndefinitely)
        sleepingThread.Name = "Sleeping"
        sleepingThread.Start()
        Thread.Sleep(2000)
        sleepingThread.Interrupt()
        sleepingThread.Join()
    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)
        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.

Im Beispiel wird aufgerufen Thread.Join , um den aufrufenden Thread zu blockieren, bis die Ausführung des unterbrochenen Threads beendet ist.

Unterbrechen von Threads

Sie können einen wartenden Thread unterbrechen, indem Sie die Thread.Interrupt Methode für den blockierten Thread aufrufen, um eine ThreadInterruptedException auszulösen, wodurch der Thread aus dem Blockierungsaufruf herausgelöst wird. Der Thread sollte ThreadInterruptedException abfangen und geeignete Maßnahmen ergreifen, um weiterzuarbeiten. Wenn der Thread die Ausnahme ignoriert, fängt die Laufzeit die Ausnahme ab und beendet den Thread.

Hinweis

Wenn der Zielthread nicht blockiert ist, wenn Thread.Interrupt aufgerufen wird, wird der Thread erst unterbrochen, wenn er blockiert. Wenn der Thread nie blockiert, kann er ohne Unterbrechung abgeschlossen werden.

Wenn es sich bei einer Wartezeit um eine verwaltete Wartezeit handelt, wird Thread.Interrupt den Thread sofort aktivieren. Wenn es sich bei einer Wartezeit um eine nicht verwaltete Wartezeit handelt (z. B. ein Plattformaufruf an die Win32 WaitForSingleObject-Funktion), kann Thread.Interrupt die Steuerung des Threads erst wieder übernehmen, wenn er in den verwalteten Code zurückkehrt oder diesen aufruft. Im verwalteten Code lautet das Verhalten wie folgt:

Siehe auch