暫停和中斷執行緒
最常見之同步處理執行緒活動的方式為封鎖及釋放執行緒、鎖定物件或程式碼區域。 如需有關這些鎖定和封鎖機制的詳細資訊,請參閱同步處理原始物件概觀。
您也可以讓執行緒自己進入睡眠。 當執行緒已封鎖或睡眠中,您可以使用 ThreadInterruptedException 解除其等候狀態。
Thread.Sleep 方法
呼叫 Thread.Sleep 方法會導致立即封鎖目前執行緒,封鎖時間為您傳遞至方法的毫秒數或時間間隔,並且會將剩餘的時間配量讓與另一個執行緒。 該時間間隔過去後,睡眠中的執行緒便會繼續執行。
執行緒無法呼叫另一個執行緒上的 Thread.Sleep。 Thread.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.Interrupt 和 Thread.Abort 兩者都會立即喚醒執行緒。 如果等候是非受控的等候 (例如,平台叫用 Win32 WaitForSingleObject 函式的呼叫),則 Thread.Interrupt 和 Thread.Abort 都無法控制執行緒,直到它傳回或呼叫受控程式碼為止。 在 Managed 程式碼中,行為如下所示:
Thread.Interrupt 會從任何可能的等候中喚醒執行緒,並造成 ThreadInterruptedException 在目的執行緒中被擲回。
僅限 .NET Framework:Thread.Abort 會從任何可能的等候中喚醒執行緒,並造成 ThreadAbortException 在執行緒中被擲回。 如需詳細資訊,請參閱終結執行緒。