Compartir a través de


Pausa e interrupción de subprocesos

Las formas más comunes de sincronizar las actividades de los subprocesos son bloquear y liberar subprocesos, o bloquear objetos o regiones de código. Para obtener más información sobre estos mecanismos de cierre y bloqueo, consulte Visión general de primitivos de sincronización.

También puede hacer que los subprocesos se pongan en modo de suspensión. Cuando los subprocesos se bloquean o se ponen en modo de suspensión, puede usar una ThreadInterruptedException para interrumpir sus estados de espera.

El método Thread.Sleep

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 se le pase al método, y cede el tiempo restante de su segmento a otro subproceso. Una vez que transcurre ese intervalo, el subproceso en suspensión vuelve a ejecutarse.

Un subproceso no puede llamar a Thread.Sleep en otro subproceso. Thread.Sleep es un método estático que siempre hace que el hilo actual se duerma.

Llamar a Thread.Sleep con un valor de Timeout.Infinite hace que un hilo se suspenda hasta que otro hilo llame al método Thread.Interrupt sobre el hilo en suspensión. En el ejemplo siguiente se muestra la interrupción de un subproceso en suspensión.

using System;
using System.Threading;

public class Example
{
    public static void Main()
    {
        // Interrupt a sleeping thread.
        var sleepingThread = new Thread(SleepIndefinitely);
        sleepingThread.Name = "Sleeping";
        sleepingThread.Start();
        Thread.Sleep(2000);
        sleepingThread.Interrupt();
        sleepingThread.Join();
    }

    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.");
        }
        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.
Imports System.Threading

Module Example
    Public Sub Main()
        ' Interrupt a sleeping thread.
        Dim sleepingThread = New Thread(AddressOf SleepIndefinitely)
        sleepingThread.Name = "Sleeping"
        sleepingThread.Start()
        Thread.Sleep(2000)
        sleepingThread.Interrupt()
        sleepingThread.Join()
    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)
        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.

En el ejemplo se llama Thread.Join a para bloquear el subproceso que realiza la llamada hasta que el subproceso interrumpido finaliza la ejecución.

Interrupción de subprocesos

Puede interrumpir un subproceso en espera llamando al método Thread.Interrupt en el subproceso bloqueado para lanzar una ThreadInterruptedException, lo que permite al subproceso salir de la llamada bloqueante. El subproceso debe detectar la ThreadInterruptedException y hacer lo que sea necesario para seguir trabajando. Si el subproceso omite la excepción, el tiempo de ejecución detecta la excepción y detiene el subproceso.

Nota:

Si el subproceso de destino no está bloqueado cuando se llama a Thread.Interrupt, el subproceso no se interrumpe hasta que se bloquea. Si el subproceso nunca se bloquea, puede finalizar sin ser interrumpido.

Si una espera es una espera administrada, Thread.Interrupt reactiva el subproceso inmediatamente. Si una espera es una espera no administrada (por ejemplo, una llamada de plataforma a la función WaitForSingleObject de Win32), Thread.Interrupt no puede tomar el control del subproceso hasta que regrese o llame al código administrado. En el código administrado, el comportamiento es el siguiente:

Consulte también