暂停和中断线程Pausing and interrupting threads

同步线程活动最常见的方法是阻止和释放线程,或者锁定对象或代码区域。The most common ways to synchronize the activities of threads are to block and release threads, or to lock objects or regions of code. 有关这些锁定和阻止机制的详细信息,请参阅同步基元概述For more information on these locking and blocking mechanisms, see Overview of Synchronization Primitives.

也可使线程将自身置于睡眠状态。You can also have threads put themselves to sleep. 当线程被阻止或处于休眠状态时,可以使用 ThreadInterruptedException 使它们脱离等待状态。When threads are blocked or sleeping, you can use a ThreadInterruptedException to break them out of their wait states.

Thread.Sleep 方法The Thread.Sleep method

调用 Thread.Sleep 方法会导致当前线程立即受阻止,时间为传递到方法的毫秒数或时间间隔,结果是将时间片的剩余部分生成给其他线程。Calling the Thread.Sleep method causes the current thread to immediately block for the number of milliseconds or the time interval you pass to the method, and yields the remainder of its time slice to another thread. 受阻时间过后,休眠线程继续执行。Once that interval elapses, the sleeping thread resumes execution.

一个线程不能调用另一线程上的 Thread.SleepOne thread cannot call Thread.Sleep on another thread. Thread.Sleep 是一种始终让当前线程进入睡眠状态的静态方法。Thread.Sleep is a static method that always causes the current thread to sleep.

调用 Thread.Sleep(值为 Timeout.Infinite)可以让线程进入睡眠状态,直到另一个对睡眠线程调用 Thread.Interrupt 方法的线程中断它,或直到 Thread.Abort 方法调用终止它。Calling Thread.Sleep with a value of Timeout.Infinite causes a thread to sleep until it is interrupted by another thread that calls the Thread.Interrupt method on the sleeping thread, or until it is terminated by a call to its Thread.Abort method. 下面的示例阐释了这两种中断休眠线程的方法。The following example illustrates both methods of interrupting a sleeping thread.

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.

中断线程Interrupting threads

可以中断正在等待的线程,具体操作是对受阻止的线程调用 Thread.Interrupt 方法,从而抛出 ThreadInterruptedException,以中断对线程执行的阻止调用。You can interrupt a waiting thread by calling the Thread.Interrupt method on the blocked thread to throw a ThreadInterruptedException, which breaks the thread out of the blocking call. 线程应该捕获 ThreadInterruptedException 并执行任何适于继续工作的操作。The thread should catch the ThreadInterruptedException and do whatever is appropriate to continue working. 如果线程忽略该异常,则运行时捕获异常,并停止该线程。If the thread ignores the exception, the runtime catches the exception and stops the thread.

备注

如果在调用 Thread.Interrupt 时,未阻止目标线程,则线程在被阻止前将不会中断。If the target thread is not blocked when Thread.Interrupt is called, the thread is not interrupted until it blocks. 如果线程永远不被阻止,则它可在不被中断的情况下完成。If the thread never blocks, it could complete without ever being interrupted.

如果等待是托管的等待,则 Thread.InterruptThread.Abort 都会立即唤醒线程。If a wait is a managed wait, then Thread.Interrupt and Thread.Abort both wake the thread immediately. 如果等待是非托管等待(例如,调用 Win32 WaitForSingleObject 函数的平台调用),Thread.InterruptThread.Abort 都不能控制线程,直到它返回到或调用托管代码。If a wait is an unmanaged wait (for example, a platform invoke call to the Win32 WaitForSingleObject function), neither Thread.Interrupt nor Thread.Abort can take control of the thread until it returns to or calls into managed code. 在托管代码中,该行为如下:In managed code, the behavior is as follows:

请参阅See also