Pausa e interrupción de subprocesosPausing and interrupting threads

Las maneras más habituales de sincronizar las actividades de los subprocesos son bloquear y liberar subprocesos, o bloquear objetos o regiones de código.The most common ways to synchronize the activities of threads are to block and release threads, or to lock objects or regions of code. Para más información sobre estos bloqueos y mecanismos de bloque, consulte Información general sobre los primitivos de sincronización.For more information on these locking and blocking mechanisms, see Overview of Synchronization Primitives.

También puede hacer que los subprocesos se pongan en modo de suspensión.You can also have threads put themselves to sleep. Cuando los subprocesos se bloquean o se ponen en modo de suspensión, puede usar una ThreadInterruptedException para interrumpir sus estados de espera.When threads are blocked or sleeping, you can use a ThreadInterruptedException to break them out of their wait states.

El método Thread.SleepThe Thread.Sleep method

Al llamar al método Thread.Sleep, el subproceso actual se bloquea inmediatamente durante el número de milisegundos o el intervalo de tiempo que pase al método, y el resto de su intervalo de tiempo se dedica a otro subproceso.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. Una vez que transcurre ese intervalo, el subproceso en suspensión vuelve a ejecutarse.Once that interval elapses, the sleeping thread resumes execution.

Un subproceso no puede llamar a Thread.Sleep en otro subproceso.One thread cannot call Thread.Sleep on another thread. Thread.Sleep es un método estático que siempre hace que el subproceso actual entre en modo de suspensión.Thread.Sleep is a static method that always causes the current thread to sleep.

Al llamar a Thread.Sleep con un valor de Timeout.Infinite, un subproceso entra en modo de suspensión hasta que lo interrumpe otro subproceso que llama al método Thread.Interrupt en el subproceso suspendido o hasta que una llamada al método Thread.Abort lo termina.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. En el ejemplo siguiente se muestran ambos métodos para interrumpir un subproceso en suspensión.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.

Interrupción de subprocesosInterrupting threads

Puede interrumpir un subproceso en espera llamando al método Thread.Interrupt en el subproceso bloqueado para generar ThreadInterruptedException, que saca al subproceso de la llamada de bloqueo.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. El subproceso debe detectar la ThreadInterruptedException y hacer lo que sea necesario para seguir trabajando.The thread should catch the ThreadInterruptedException and do whatever is appropriate to continue working. Si el subproceso pasa por alto la excepción, el tiempo de ejecución detecta la excepción y detiene el subproceso.If the thread ignores the exception, the runtime catches the exception and stops the thread.

Nota

Si el subproceso de destino no está bloqueado cuando se llama a Thread.Interrupt, el subproceso no se interrumpe hasta que se bloquea.If the target thread is not blocked when Thread.Interrupt is called, the thread is not interrupted until it blocks. Si el subproceso nunca se bloquea, puede finalizar sin ser interrumpido.If the thread never blocks, it could complete without ever being interrupted.

Si una espera es administrada, tanto Thread.Interrupt como Thread.Abort activan el subproceso inmediatamente.If a wait is a managed wait, then Thread.Interrupt and Thread.Abort both wake the thread immediately. Si una espera es de tipo no administrado (por ejemplo, una llamada de invocación de plataforma a la función WaitForSingleObject de Win32), ni Thread.Abort ni Thread.Interrupt pueden tomar el control del subproceso hasta que este vuelva o llame a código administrado.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. En código administrado, el comportamiento es el siguiente:In managed code, the behavior is as follows:

Vea tambiénSee also