Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
As formas mais comuns de sincronizar as atividades das threads são bloquear e libertar threads, ou bloquear objetos ou regiões de código. Para obter mais informações sobre estes mecanismos de bloqueio e bloqueio, consulte Visão Geral das Primitivas de Sincronização.
Também podes fazer com que os fios se adormecam sozinhos. Quando as threads estão bloqueadas ou em suspensão, pode usar um ThreadInterruptedException para retirá-las do seu estado de espera.
O método Thread.Sleep
Chamar o método Thread.Sleep faz com que a linha de execução atual bloqueie imediatamente pelo número de milissegundos ou pelo intervalo de tempo que é passado ao método, e dá o restante da sua fatia de tempo a outra linha de execução. Quando esse intervalo termina, o fio de dormência retoma a execução.
Uma thread não pode chamar Thread.Sleep em outra thread. Thread.Sleep é um método estático que faz sempre com que a thread corrente entre em suspensão.
Chamar Thread.Sleep com um valor de Timeout.Infinite faz com que uma thread durma até que outra thread chame o método Thread.Interrupt na thread que está a dormir. O exemplo seguinte ilustra a interrupção de um fio de suspensão.
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.
O exemplo chama Thread.Join para bloquear o subprocesso chamador até que o subprocesso interrompido termine a execução.
Interrupção de threads
Pode interromper uma thread em espera chamando o método Thread.Interrupt na thread bloqueada para lançar um ThreadInterruptedException, que remove a thread da chamada de bloqueio. A linha deve apanhar o ThreadInterruptedException e fazer o que for necessário para continuar a trabalhar. Se a thread ignorar a exceção, o tempo de execução apanha a exceção e pára a thread.
Observação
Se o thread de destino não estiver bloqueado quando Thread.Interrupt for chamado, o thread não será interrompido até ser bloqueado. Se a linha de execução nunca bloquear, pode concluir-se sem nunca ser interrompida.
Se a espera for uma espera gerida, Thread.Interrupt ativa o thread imediatamente. Se uma espera for uma espera não gerida (por exemplo, uma chamada de plataforma para a função WaitForSingleObject do Win32), Thread.Interrupt não pode assumir controlo sobre o thread até que ele retorne ou faça uma chamada para código gerido. No código gerido, o comportamento é o seguinte:
Thread.Interrupt acorda uma thread de qualquer espera em que possa estar e faz com que a ThreadInterruptedException seja lançada na thread de destino.
.NET Framework apenas: Thread.Abort desperta um thread de qualquer espera em que possa estar e faz com que um ThreadAbortException seja lançado no thread. Para obter mais informações, veja Destruir Threads.