Após chamar a suspensão em um método, o programa continuará sendo executado em segundo plano (sem criar novo encadeamento)? Além disso, se eu chamar suspensão em um novo thread, o thread principal continuará seu trabalho?
Jay Nirgudkar
@JayNirgudkar, o segmento que chama Sleep será interrompido. Outros threads não são afetados.
Isak Savo 28/05
Não é garantido que isso seja preciso.
Akumaburn 28/10
150
Existem basicamente três opções para aguardar (quase) em qualquer linguagem de programação:
Espera solta
Executando blocos de encadeamento por um tempo determinado (= não consome poder de processamento)
Nenhum processamento é possível no encadeamento bloqueado / em espera
Não é tão preciso
Espera apertada (também chamada de loop apertado)
O processador fica MUITO ocupado durante todo o intervalo de espera (na verdade, geralmente consome 100% do tempo de processamento de um núcleo)
Algumas ações podem ser executadas enquanto aguarda
Muito preciso
Combinação dos 2 anteriores
Geralmente, combina eficiência de processamento de 1. e precisão + capacidade de fazer algo de 2.
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 possibleif(stopwatch.ElapsedMilliseconds>= millisecondsToWait){break;}}
Também poderíamos usar DateTime.Nowou 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 POSSIBLEif(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.
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.
usingSystem.Runtime.InteropServices;[DllImport("winmm.dll",EntryPoint="timeBeginPeriod",SetLastError=true)]privatestaticexternuintTimeBeginPeriod(uint uMilliseconds);[DllImport("winmm.dll",EntryPoint="timeEndPeriod",SetLastError=true)]privatestaticexternuintTimeEndPeriod(uint uMilliseconds);/**
* Extremely accurate sleep is needed here to maintain performance so system resolution time is increased
*/privatevoid accurateSleep(int milliseconds){//Increase timer resolution from 20 miliseconds to 1 milisecondTimeBeginPeriod(1);Stopwatch stopwatch =newStopwatch();//Makes use of QueryPerformanceCounter WIN32 API
stopwatch.Start();while(stopwatch.ElapsedMilliseconds< milliseconds){//So we don't burn cpu cyclesif((milliseconds - stopwatch.ElapsedMilliseconds)>20){Thread.Sleep(5);}else{Thread.Sleep(1);}}
stopwatch.Stop();//Set it back to normal.TimeEndPeriod(1);}
Respostas:
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.fonte
Existem basicamente três opções para aguardar (quase) em qualquer linguagem de programação:
para 1. - Espera solta em C #:
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 # é:
Também poderíamos usar
DateTime.Now
ou outros meios de medição de tempo, masStopwatch
é muito mais rápido (e isso realmente se tornaria visível em loop apertado).para 3. - Combinação:
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).
fonte
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.fonte
Como agora você tem o recurso assíncrono / espera, a melhor maneira de dormir por 50ms é usando o Task.Delay:
Ou, se você estiver direcionando o .NET 4 (com Async CTP 3 para VS2010 ou Microsoft.Bcl.Async), use:
Dessa forma, você não bloqueará o thread da interface do usuário.
fonte
FlushAsync
versão.async
declaração é chamarTask.Delay(50).Wait();
Use este código
fonte
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.
fonte
Para legibilidade:
fonte
A partir do .NET Framework 4.5, você pode usar:
fonte
Melhor dos dois mundos:
fonte