Comment puis-je faire dormir mon programme C # pendant 50 ms?

Comment puis-je mettre mon programme C # en veille pendant 50 millisecondes?

Cela peut sembler une question facile, mais j’ai un moment de défaillance cérébrale temporaire!

System.Threading.Thread.Sleep(50); 

Rappelez-vous cependant que cela dans le thread de l’interface graphique principale empêchera votre interface graphique de se mettre à jour (cela semblera “lent”)

Il suffit de retirer le ; pour le faire fonctionner également pour VB.net.

Il y a fondamentalement 3 choix pour attendre dans (presque) n’importe quel langage de programmation:

  1. Loose attente
    • Exécution de blocs de threads pour un temps donné (= ne consum pas de puissance de traitement)
    • Aucun traitement n’est possible sur le thread bloqué / en attente
    • Pas si précis
  2. Attente serrée (aussi appelée boucle serrée)
    • le processeur est TRÈS occupé pendant tout l’intervalle d’attente (en fait, il consum généralement 100% du temps de traitement d’un cœur)
    • Certaines actions peuvent être effectuées en attendant
    • Tres précis
  3. Combinaison des 2 précédents
    • Il combine généralement l’efficacité de traitement de 1. et la précision + la capacité de faire quelque chose de 2.

pour 1. – Loose attente en C #:

 Thread.Sleep(numberOfMilliseconds); 

Cependant, le programmateur de threads Windows entraîne une exactitude de Sleep() d’environ 15 ms (de sorte que Sleep peut facilement attendre 20 ms, même s’il est prévu qu’il attend juste 1 ms).

pour 2. – L’attente serrée en C # est:

 Stopwatch stopwatch = Stopwatch.StartNew(); while (true) { //some other processing to do possible if (stopwatch.ElapsedMilliseconds >= millisecondsToWait) { break; } } 

Nous pourrions également utiliser DateTime.Now ou d’autres moyens de mesure du temps, mais le Stopwatch est beaucoup plus rapide (et cela deviendrait vraiment visible en boucle serrée).

pour 3. – Combinaison:

 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 } 

Ce code bloque régulièrement le thread pendant 1 ms (ou un peu plus, en fonction de la planification des threads du système d’exploitation). D’autres traitements peuvent toujours être effectués entre les blocages (tels que la mise à jour de l’interface utilisateur, la gestion des événements ou les interactions / communications).

Vous ne pouvez pas spécifier un temps de sumil exact dans Windows. Vous avez besoin d’un système d’exploitation en temps réel pour cela. Le mieux que vous puissiez faire est de spécifier un temps de sumil minimum . Ensuite, le programmateur doit réveiller votre fil de discussion après cela. Et n’appelez jamais .Sleep() sur le thread d’interface graphique.

Puisque maintenant vous avez la fonctionnalité asynchrone / wait, la meilleure façon de dormir pendant 50ms est d’utiliser Task.Delay:

 async void foo() { // something await Task.Delay(50); } 

Ou, si vous ciblez .NET 4 (avec Async CTP 3 pour VS2010 ou Microsoft.Bcl.Async), vous devez utiliser:

 async void foo() { // something await TaskEx.Delay(50); } 

De cette façon, vous ne bloquerez pas le thread d’interface utilisateur.

Utilisez ce code

 using System.Threading; // ... Thread.Sleep(50); 
 Thread.Sleep(50); 

L’exécution du thread ne sera pas planifiée par le système d’exploitation pendant la durée spécifiée. Cette méthode modifie l’état du thread pour inclure WaitSleepJoin.

Cette méthode n’effectue pas le pompage standard COM et SendMessage. Si vous devez vous arrêter sur un thread qui possède STAThreadAtsortingbute, mais que vous souhaitez effectuer un pompage standard COM et SendMessage, envisagez d’utiliser l’une des surcharges de la méthode Join qui spécifie un intervalle d’expiration.

 Thread.Join 
 Thread.Sleep 

Pour plus de lisibilité:

 using System.Threading; Thread.Sleep(TimeSpan.FromMilliseconds(50)); 

Le meilleur des deux mondes:

 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); }