暂停和中断线程
同步线程活动最常见的方法是阻止和释放线程,或者锁定对象或代码区域。 有关这些锁定和阻止机制的详细信息,请参阅同步基元概述。
也可使线程将自身置于睡眠状态。 当线程被阻止或处于休眠状态时,可以使用 ThreadInterruptedException 使它们脱离等待状态。
Thread.Sleep 方法
调用 Thread.Sleep 方法会导致当前线程立即受阻止,时间为传递到方法的毫秒数或时间间隔,结果是将时间片的剩余部分生成给其他线程。 受阻时间过后,休眠线程继续执行。
一个线程不能调用另一线程上的 Thread.Sleep。 Thread.Sleep 是一种始终让当前线程进入睡眠状态的静态方法。
调用 Thread.Sleep(值为 Timeout.Infinite)可以让线程进入睡眠状态,直到另一个对睡眠线程调用 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 时,未阻止目标线程,则线程在被阻止前将不会中断。 如果线程永远不被阻止,则它可在不被中断的情况下完成。
如果等待是托管的等待,则 Thread.Interrupt 和 Thread.Abort 都会立即唤醒线程。 如果等待是非托管等待(例如,调用 Win32 WaitForSingleObject 函数的平台调用),Thread.Interrupt 和 Thread.Abort 都不能控制线程,直到它返回到或调用托管代码。 在托管代码中,该行为如下:
Thread.Interrupt 将线程从其可能处于的任何等待中唤醒,并导致在目标线程中引发 ThreadInterruptedException。
仅限 .NET Framework:Thread.Abort 将线程从可能处于的任何等待中唤醒,并导致 ThreadAbortException 在线程中抛出。 有关详细信息,请参阅销毁线程。