Partilhar via


Pausando e interrompendo threads

As maneiras mais comuns de sincronizar as atividades de threads são bloquear e liberar threads, ou bloquear objetos ou regiões de código. Para obter mais informações sobre esses mecanismos de bloqueio e bloqueio, consulte Visão geral das primitivas de sincronização.

Você também pode fazer com que os fios se coloquem para dormir. Quando os threads estão bloqueados ou em suspensão, você pode usar um ThreadInterruptedException para quebrá-los de seus estados de espera.

O método Thread.Sleep

Chamar o Thread.Sleep método faz com que o thread atual bloqueie imediatamente o número de milissegundos ou o intervalo de tempo que você passa para o método e produz o restante de sua fatia de tempo para outro thread. Uma vez decorrido esse intervalo, o fio adormecido retoma a execução.

Um thread não pode chamar Thread.Sleep outro thread. Thread.Sleep é um método estático que sempre faz com que o thread atual entre em suspensão.

Chamar Thread.Sleep com um valor de Timeout.Infinite faz com que um thread entre em repouso até que seja interrompido por outro thread que chama o Thread.Interrupt método no thread em repouso ou até que ele seja encerrado por uma chamada para seu Thread.Abort método. O exemplo a seguir ilustra ambos os métodos de interrupção de um fio em suspensão.

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.

Interrompendo threads

Você pode interromper um thread de espera chamando o Thread.Interrupt método no thread bloqueado para lançar um ThreadInterruptedException, que quebra o thread da chamada de bloqueio. O fio deve pegar o e fazer o ThreadInterruptedException que for apropriado para continuar trabalhando. Se o thread ignorar a exceção, o tempo de execução captura a exceção e interrompe o thread.

Nota

Se o thread de destino não for bloqueado quando Thread.Interrupt for chamado, o thread não será interrompido até bloquear. Se o thread nunca bloquear, ele pode ser concluído sem nunca ser interrompido.

Se uma espera é uma espera gerenciada, então Thread.Interrupt e Thread.Abort ambos acordam o thread imediatamente. Se uma espera for uma espera não gerenciada (por exemplo, uma chamada de invocação de plataforma para a função Win32 WaitForSingleObject ), nem Thread.Interrupt Thread.Abort nem poderá assumir o controle do thread até que ele retorne ou chame o código gerenciado. No código gerenciado, o comportamento é o seguinte:

Consulte também