Pozastavení a přerušení vláken

Nejběžnějšími způsoby synchronizace aktivit vláken jsou blokování a vydávání vláken nebo uzamčení objektů nebo oblastí kódu. Další informace o těchto mechanismech uzamčení a blokování najdete v tématu Přehled primitiv synchronizace.

Můžete také mít vlákna umístit se do režimu spánku. Pokud jsou vlákna blokovaná nebo spí, můžete je použít ThreadInterruptedException k jejich přerušení ze stavu čekání.

Metoda Thread.Sleep

Thread.Sleep Volání metody způsobí, že aktuální vlákno okamžitě zablokuje počet milisekund nebo časový interval, který metodě předáte, a získá zbytek jeho časového řezu do jiného vlákna. Jakmile tento interval uplynou, vlákno spánku obnoví provádění.

Jedno vlákno nemůže volat Thread.Sleep v jiném vlákně. Thread.Sleep je statická metoda, která vždy způsobí, že aktuální vlákno spí.

Volání Thread.Sleep s hodnotou Timeout.Infinite způsobí, že vlákno bude do režimu spánku, dokud se nepřeruší jiným vláknem, které volá Thread.Interrupt metodu ve vlákně spánku, nebo dokud se neukončí voláním jeho Thread.Abort metody. Následující příklad ukazuje obě metody přerušení spící vlákno.

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.

Přerušení vláken

Můžete přerušit čekající vlákno voláním Thread.Interrupt metody na blokované vlákno vyvolat , ThreadInterruptedExceptionkterý přeruší vlákno mimo blokující volání. Vlákno by mělo zachytit ThreadInterruptedException a udělat vše, co je vhodné pro pokračování v práci. Pokud vlákno tuto výjimku ignoruje, modul runtime výjimku zachytí a zastaví vlákno.

Poznámka:

Pokud cílové vlákno není blokováno při Thread.Interrupt volání, vlákno není přerušeno, dokud ho nezablokuje. Pokud vlákno nikdy nezablokuje, mohlo by se dokončit bez přerušení.

Pokud je čekání spravované čekání, pak Thread.Interrupt a Thread.Abort obě probudit vlákno okamžitě. Pokud je čekání nespravované čekání (například volání volání platformy vyvolání funkce Win32 WaitForSingleObject ), Thread.Interrupt ani Thread.Abort nemůže převzít kontrolu nad vláknem, dokud se nevrátí do spravovaného kódu nebo volání do spravovaného kódu. Ve spravovaném kódu je chování následující:

Viz také