同步處理線程活動的最常見方式是封鎖和釋放線程,或鎖定程式碼的物件或區域。 如需這些鎖定和封鎖機制的詳細資訊,請參閱 同步處理基本類型概觀。
您也可以讓線程自行進入睡眠狀態。 當執行緒遭到封鎖或處於睡眠狀態時,您可以使用 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 '{Thread.CurrentThread.Name}' about to sleep indefinitely.");
try {
Thread.Sleep(Timeout.Infinite);
}
catch (ThreadInterruptedException) {
Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' awoken.");
}
catch (ThreadAbortException) {
Console.WriteLine($"Thread '{Thread.CurrentThread.Name}' aborted.");
}
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.
//
// 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 時未封鎖目標線程,則線程在封鎖之前不會中斷。 如果線程永遠不會封鎖,它就可能完成,而不會中斷。
如果等候是受控等候,則 Thread.Interrupt 和 Thread.Abort 兩者都會立即喚醒線程。 如果等候是非受控等候(例如,平台調用 Win32 WaitForSingleObject 函式),則無論是 Thread.Interrupt 或 Thread.Abort 都無法控制線程,直到它返回或進入管理代碼。 在受控語言程式碼中,行為如下:
Thread.Interrupt 會解除任何等待狀態的線程,並在目的地線程中拋出 ThreadInterruptedException。
僅限 .NET Framework:Thread.Abort 會將執行緒從任何等候中喚醒,並在該執行緒上擲回 ThreadAbortException。 如需詳細資訊,請參閱 終結線程。
另請參閱
- Thread
- ThreadInterruptedException
- ThreadAbortException
- 線程
- 使用執行緒與多執行緒處理
- 同步處理基本類型概觀