Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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:
Thread.Interrupt activa un subproceso de cualquier tipo de espera que pueda haber y hace que se genere una ThreadInterruptedException en el subproceso de destino.
Solo .NET Framework: Thread.Abort activa un subproceso de cualquier tipo de espera en el que pueda estar y hace que se inicie una ThreadAbortException en el subproceso. Para obtener detalles, vea Destrucción de subprocesos.