Como faço para meu programa C # dormir por 50 milissegundos?
Pode parecer uma pergunta fácil, mas estou tendo um momento temporário de insuficiência cerebral!
Como faço para meu programa C # dormir por 50 milissegundos?
Pode parecer uma pergunta fácil, mas estou tendo um momento temporário de insuficiência cerebral!
Respostas:
System.Threading.Thread.Sleep(50);
Lembre-se, porém, que fazer isso no thread principal da GUI impedirá a atualização da GUI (ela parecerá "lenta")
Basta remover o ;
para fazê-lo funcionar no VB.net também.
Existem basicamente três opções para aguardar (quase) em qualquer linguagem de programação:
para 1. - Espera solta em C #:
Thread.Sleep(numberOfMilliseconds);
No entanto, o agendador de encadeamentos do Windows faz com que a precisão Sleep()
fique em torno de 15ms (para que o Sleep possa esperar facilmente por 20ms, mesmo que agendado para esperar apenas por 1ms).
para 2. - A espera apertada em C # é:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do possible
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
}
Também poderíamos usar DateTime.Now
ou outros meios de medição de tempo, mas Stopwatch
é muito mais rápido (e isso realmente se tornaria visível em loop apertado).
para 3. - Combinação:
Stopwatch stopwatch = Stopwatch.StartNew();
while (true)
{
//some other processing to do STILL POSSIBLE
if (stopwatch.ElapsedMilliseconds >= millisecondsToWait)
{
break;
}
Thread.Sleep(1); //so processor can rest for a while
}
Esse código bloqueia regularmente o encadeamento por 1ms (ou um pouco mais, dependendo do agendamento do encadeamento do SO), para que o processador não fique ocupado durante esse período de bloqueio e o código não consuma 100% da energia do processador. Outro processamento ainda pode ser realizado entre os bloqueios (como: atualização da interface do usuário, manipulação de eventos ou interação / comunicação).
Você não pode especificar um tempo exato de suspensão no Windows. Você precisa de um sistema operacional em tempo real para isso. O melhor que você pode fazer é especificar um tempo mínimo de sono. Depois, cabe ao agendador ativar seu encadeamento depois disso. E nunca chame .Sleep()
o thread da GUI.
Como agora você tem o recurso assíncrono / espera, a melhor maneira de dormir por 50ms é usando o Task.Delay:
async void foo()
{
// something
await Task.Delay(50);
}
Ou, se você estiver direcionando o .NET 4 (com Async CTP 3 para VS2010 ou Microsoft.Bcl.Async), use:
async void foo()
{
// something
await TaskEx.Delay(50);
}
Dessa forma, você não bloqueará o thread da interface do usuário.
FlushAsync
versão.
async
declaração é chamarTask.Delay(50).Wait();
Use este código
using System.Threading;
// ...
Thread.Sleep(50);
Thread.Sleep(50);
O encadeamento não será agendado para execução pelo sistema operacional pela quantidade de tempo especificada. Este método altera o estado do thread para incluir WaitSleepJoin.
Esse método não executa o bombeamento COM e SendMessage padrão. Se você precisar dormir em um encadeamento que possui STAThreadAttribute, mas deseja executar o bombeamento COM e SendMessage padrão, considere usar uma das sobrecargas do método Join que especifica um intervalo de tempo limite.
Thread.Join
Para legibilidade:
using System.Threading;
Thread.Sleep(TimeSpan.FromMilliseconds(50));
Melhor dos dois mundos:
using System.Runtime.InteropServices;
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)]
private static extern uint TimeBeginPeriod(uint uMilliseconds);
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)]
private static extern uint TimeEndPeriod(uint uMilliseconds);
/**
* Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
*/
private void accurateSleep(int milliseconds)
{
//Increase timer resolution from 20 miliseconds to 1 milisecond
TimeBeginPeriod(1);
Stopwatch stopwatch = new Stopwatch();//Makes use of QueryPerformanceCounter WIN32 API
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < milliseconds)
{
//So we don't burn cpu cycles
if ((milliseconds - stopwatch.ElapsedMilliseconds) > 20)
{
Thread.Sleep(5);
}
else
{
Thread.Sleep(1);
}
}
stopwatch.Stop();
//Set it back to normal.
TimeEndPeriod(1);
}