スレッドの一時中断および中断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.Sleep を呼び出すことはできません。One thread cannot call Thread.Sleep on another thread. Thread.Sleep は静的メソッドであり、常に現在のスレッドがスリープ状態になります。Thread.Sleep is a static method that always causes the current thread to sleep.

Timeout.Infinite の値を指定して Thread.Sleep を呼び出すと、スリープ状態のスレッドで 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