Dela via


Pausa och avbryta trådar

De vanligaste sätten att synkronisera trådarnas aktiviteter är att blockera och frigöra trådar, eller att låsa objekt eller regioner med kod. Mer information om dessa låsnings- och blockeringsmekanismer finns i Översikt över synkroniserings primitiver.

Du kan också låta trådar försätta sig själva i viloläge. När trådar blockeras eller sover kan du använda en ThreadInterruptedException för att bryta dem ur deras väntetillstånd.

Metoden Thread.Sleep

Thread.Sleep Om du anropar metoden blockeras den aktuella tråden omedelbart för antalet millisekunder eller det tidsintervall som du skickar till metoden och ger resten av dess tidssektor till en annan tråd. När det intervallet har gått återupptas körningen av den vilande tråden.

En tråd kan inte anropa Thread.Sleep en annan tråd. Thread.Sleep är en statisk metod som alltid gör att den aktuella tråden försätts i viloläge.

Om en Thread.Sleep tråd anropas med värdet Timeout.Infinite viloläge tills den avbryts av en annan tråd som anropar Thread.Interrupt metoden i vilotråden, eller tills den avslutas av ett anrop till metoden Thread.Abort . I följande exempel visas båda metoderna för att avbryta en vilotråd.

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.

Avbryter trådar

Du kan avbryta en väntande tråd genom att anropa Thread.Interrupt metoden på den blockerade tråden för att kasta en ThreadInterruptedException, som bryter tråden ur blockeringsanropet. Tråden ThreadInterruptedException bör fånga och göra vad som är lämpligt för att fortsätta arbeta. Om tråden ignorerar undantaget fångar körningen undantaget och stoppar tråden.

Kommentar

Om måltråden inte blockeras när Thread.Interrupt anropas avbryts inte tråden förrän den blockeras. Om tråden aldrig blockerar kan den slutföras utan att någonsin avbrytas.

Om en väntan är en hanterad väntan Thread.Interrupt Thread.Abort aktiverar båda tråden omedelbart. Om en väntetid är en ohanterad väntan (till exempel en plattform anropar anropet till funktionen Win32 WaitForSingleObject ) kan varken Thread.Interrupt eller Thread.Abort ta kontroll över tråden förrän den återgår till eller anropar till hanterad kod. I hanterad kod är beteendet följande:

Se även