HOWTO · Csharp
Como fazer um temporizador de atraso em C#
Este artigo apresenta como fazer um temporizador de atraso em C#. Ele inclui quatro métodos diferentes: Thread.Sleep(), Task.Delay(), System.Timers.Timer e System.Threading.Timer.
Nesta página
Para adicionar um atraso em C#, escolha Thread.Sleep() para bloquear o thread atual, Task.Delay() para aguardar de forma assíncrona ou uma classe de temporizador para agendar um callback. Os exemplos abaixo usam um intervalo de dois segundos e mostram como cada opção se comporta. Eles não foram executados no runtime fornecido, portanto nenhuma saída observada é alegada.
Usar o método Thread.Sleep() para criar um atraso em C#
Thread.Sleep() pausa o thread atual pelo número especificado de milissegundos. Como esse thread não pode realizar outro trabalho durante a espera, use essa abordagem apenas quando o bloqueio for apropriado, como em um programa de console síncrono curto.
Este exemplo completo imprime uma mensagem, aguarda dois segundos e, em seguida, imprime outra mensagem:
using System;
using System.Threading;
class DelayExample
{
static void Main()
{
Console.WriteLine("The delay starts.");
Thread.Sleep(2000);
Console.WriteLine("The delay ends.");
}
}
O argumento está em milissegundos, portanto 2000 solicita uma espera de dois segundos. O tempo real decorrido pode variar de acordo com o agendamento do sistema.
Usar o método Task.Delay() para criar um atraso em C#
Task.Delay() cria uma tarefa que é concluída após o intervalo solicitado. Aguardá-la com await em um método assíncrono permite que esse método ceda enquanto espera, ao contrário de Thread.Sleep(), que ocupa o thread atual. Chame o método assíncrono a partir do fluxo assíncrono existente do seu aplicativo.
Este exemplo completo mantém a espera assíncrona em um método separado e usa um ponto de entrada síncrono para chamá-lo:
using System;
using System.Threading.Tasks;
class DelayExample
{
static void Main()
{
RunAsync().GetAwaiter().GetResult();
}
static async Task RunAsync()
{
Console.WriteLine("Before the delay");
await Task.Delay(2000);
Console.WriteLine("After the delay");
}
}
A expressão await retoma RunAsync após a conclusão da tarefa de atraso. Em um aplicativo que já usa métodos assíncronos, aguarde Task.Delay(2000) diretamente com await em vez de bloquear o ponto de entrada para aguardar a tarefa.
Usar a classe System.Timers.Timer para criar um atraso em C#
System.Timers.Timer gera um evento Elapsed após o seu Interval em milissegundos. Defina AutoReset como false para um único evento; defina-o como true quando o evento deve se repetir no intervalo. O callback é orientado a eventos, portanto iniciar um temporizador não pausa a próxima linha de código.
Este exemplo completo aguarda o evento único antes de o programa de console terminar:
using System;
using System.Threading;
using System.Timers;
class DelayExample
{
static void Main()
{
using (var completed = new ManualResetEvent(false))
using (var timer = new System.Timers.Timer(2000))
{
timer.AutoReset = false;
timer.Elapsed += (sender, args) =>
{
Console.WriteLine("Timer elapsed.");
completed.Set();
};
Console.WriteLine("Timer started.");
timer.Start();
completed.WaitOne();
}
}
}
WaitOne() mantém este exemplo de console ativo até que o manipulador de evento sinalize a conclusão. Em um aplicativo de execução mais longa, mantenha o aplicativo ativo de acordo com seu loop de eventos normal ou tempo de vida do serviço, em vez de adicionar uma espera bloqueante apenas para o temporizador.
Usar a classe System.Threading.Timer para criar um atraso em C#
System.Threading.Timer agenda um callback com um tempo de vencimento inicial e um período. Ambos os valores estão em milissegundos. Use Timeout.Infinite para o período quando o callback deve ser executado uma vez; forneça um período finito para agendar callbacks repetidos. O callback é executado separadamente do código que inicia o temporizador.
Este exemplo completo agenda um callback após dois segundos e o aguarda antes de terminar:
using System;
using System.Threading;
class DelayExample
{
static void Main()
{
using (var completed = new ManualResetEvent(false))
using (var timer = new System.Threading.Timer(
state =>
{
Console.WriteLine("Timer callback.");
completed.Set();
},
null,
2000,
Timeout.Infinite))
{
Console.WriteLine("Timer scheduled.");
completed.WaitOne();
}
}
}
O tempo de vencimento agenda o primeiro callback dois segundos após a construção. Timeout.Infinite impede que outro callback seja agendado. A espera mantém este exemplo de console ativo por tempo suficiente para receber o callback; um aplicativo com seu próprio loop de eventos pode usar esse tempo de vida.
Conclusão
Use Thread.Sleep() para uma pausa síncrona simples quando bloquear o thread atual for aceitável. Prefira Task.Delay() com await em código assíncrono para que o método possa ceder enquanto espera. Escolha System.Timers.Timer ou System.Threading.Timer quando precisar de agendamento baseado em callbacks, com AutoReset ou o período do temporizador controlando a repetição. Os callbacks de temporizador agendam trabalho; eles não pausam a execução sequencial, e seu tempo não é uma garantia exata de relógio de parede.