暫停和中斷執行緒

最常見之同步處理執行緒活動的方式為封鎖及釋放執行緒、鎖定物件或程式碼區域。 如需有關這些鎖定和封鎖機制的詳細資訊,請參閱同步處理原始物件概觀

您也可以讓執行緒自己進入睡眠。 當執行緒已封鎖或睡眠中,您可以使用 ThreadInterruptedException 解除其等候狀態。

Thread.Sleep 方法

呼叫 Thread.Sleep 方法會導致立即封鎖目前執行緒,封鎖時間為您傳遞至方法的毫秒數或時間間隔,並且會將剩餘的時間配量讓與另一個執行緒。 該時間間隔過去後,睡眠中的執行緒便會繼續執行。

執行緒無法呼叫另一個執行緒上的 Thread.SleepThread.Sleep 是一律會導致目前執行緒進入睡眠的靜態方法。

呼叫具有 Timeout.Infinite 值的 Thread.Sleep 會造成執行緒進入睡眠,直到被另一個在睡眠中執行緒上呼叫 Thread.Interrupt 的執行緒中斷,或直到由其 Thread.Abort 方法的呼叫終止。 下列範例說明這兩種可中斷睡眠中執行緒的方法。

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.

中斷執行緒

您可藉由在封鎖的執行緒上呼叫 Thread.Interrupt 方法來中斷等候中的執行緒,以擲回 ThreadInterruptedException,這會中斷執行緒的封鎖呼叫。 執行緒應該攔截 ThreadInterruptedException並執行任何適合繼續進行的工作。 如果執行緒忽略例外狀況,則執行階段會攔截例外狀況,並停止執行緒。

注意

在呼叫 Thread.Interrupt 時,如果未封鎖目標執行緒,則到封鎖之前,執行緒不會中斷。 如果執行緒永不封鎖,它可在沒有任何中斷的情況下完成。

如果等候是 Managed 等候,那麼 Thread.InterruptThread.Abort 兩者都會立即喚醒執行緒。 如果等候是非受控的等候 (例如,平台叫用 Win32 WaitForSingleObject 函式的呼叫),則 Thread.InterruptThread.Abort 都無法控制執行緒,直到它傳回或呼叫受控程式碼為止。 在 Managed 程式碼中,行為如下所示:

另請參閱