Quel est l’impact de Thread.Sleep (1) en C #?

Dans une application Windows Thread.Sleep(1) quel est l’impact de l’appel de Thread.Sleep(1) comme illustré dans le code suivant:

 public Constructor() { Thread thread = new Thread(Task); thread.IsBackground = true; thread.Start(); } private void Task() { while (true) { // do something Thread.Sleep(1); } } 

Ce fil va-t-il encombrer tout le processeur disponible?

Quelles techniques de profilage puis-je utiliser pour mesurer l’utilisation du processeur de ce thread (autre que le gestionnaire de tâches)?

Comme indiqué, votre boucle n’engorgera pas le processeur.

Mais attention : Windows n’est pas un système d’exploitation en temps réel, vous ne recevrez donc pas 1 000 sactivités par seconde de Thread.Sleep (1). Si vous n’avez pas utilisé timeBeginPeriod pour définir votre résolution minimale, vous vous réveillerez toutes les 15 ms. Même après avoir réglé la résolution minimale sur 1 ms, vous ne vous réveillerez que toutes les 3 à 4 ms.

Pour obtenir une granularité de la timer de niveau milliseconde, vous devez utiliser la timer multimédia Win32 ( wrapper C # ).

Non, il ne va pas encombrer le processeur, il mettra simplement votre fil en pause pendant au moins aussi longtemps. Pendant que votre thread est en pause, le système d’exploitation peut planifier un autre thread, sans aucun lien avec ce processeur, pour utiliser le processeur.

Thread.Sleep (1), comme indiqué, n’engorgera pas le processeur.

Voici ce qui se passe quand un thread dort (plus ou moins):

  • Thread.Sleep est traduit en un appel système, qui à son tour déclenche une interruption (une interruption permettant au système d’exploitation de prendre le contrôle).
  • Le système d’exploitation détecte l’appel en veille et marque votre thread comme bloqué.
  • En interne, le système d’exploitation conserve une liste de threads à réveiller et à quel moment.
  • Depuis que le thread n’utilise plus le processeur, le système d’exploitation …
  • Si le processus parent n’a pas utilisé toute sa tranche de temps, le système d’exploitation planifie l’exécution d’un autre thread du processus.
  • Sinon, un autre processus (ou le processus inactif) commencera à s’exécuter.
  • Lorsque le temps est venu, votre thread sera à nouveau programmé pour l’exécution, cela ne signifie pas qu’il va commencer à s’exécuter automatiquement.

Pour finir, je ne sais pas exactement ce que vous faites, mais il semblerait que vous essayez de jouer le rôle de planificateur, c’est-à-dire de vous endormir pour donner à la CPU le temps de faire autre chose …

Dans quelques cas (très peu), tout ira bien, mais vous devriez surtout laisser le planificateur faire son travail, il en sait probablement plus que vous , et peut rendre le travail meilleur que vous ne pouvez le faire .

Comme Bob Nadler l’a mentionné, Thread.Sleep(1) ne garantit pas un temps de sumil de 1 ms.

Voici un exemple d’utilisation du minuteur multimédia Win32 pour forcer une veille de 1 ms.

  [DllImport("winmm.dll")] internal static extern uint timeBeginPeriod(uint period); [DllImport("winmm.dll")] internal static extern uint timeEndPeriod(uint period); timeBeginPeriod(1); while(true) { Thread.Sleep(1); // will sleep 1ms every time } timeEndPeriod(1); 

En testant cela dans une application graphique C #, j’ai constaté que l’application utilisait environ 50% de mon processeur.

Pour plus de discussion sur ce sujet, voir le fil de discussion suivant:

http://www.dotnet247.com/247reference/msgs/57/289291.aspx

Les temps de sumil courts doivent être évités, car un thread abandonnant sa tranche de temps reçoit un boost de priorité lorsqu’il est renvoyé, ce qui peut entraîner des changements de contexte importants. Dans une application multithread / serveur, cela peut avoir un effet de blocage car les threads se disputent le temps processeur. Utilisez plutôt des fonctions asynchrones et des objects de synchronisation tels que des sections critiques ou des mutex / sémaphores.

C’est un vieux fil de discussion qui apparaît dans beaucoup de mes recherches, mais Win7 a un nouvel ordonnanceur et semble se comporter différemment des précédents.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ConsoleApplication2 { class Program { static void Main(ssortingng[] args) { DateTime dtEnd = DateTime.Now.AddSeconds(1.0); int i = 0; while (DateTime.Now < dtEnd) { i++; Thread.Sleep(1); } Console.WriteLine(i.ToString()); i = 0; long lStart = DateTime.Now.Ticks; while (i++ < 1000) Thread.Sleep(1); long lTmp = (DateTime.Now.Ticks - lStart) / 10000; Console.WriteLine(lTmp.ToString()); Console.Read(); } } } 

Avec le code ci-dessus, mon premier résultat donnait 946. Donc, en 1 seconde avec 1 ms de sumil, j'ai eu 946 réveils. C'est très proche de 1ms.

La deuxième partie demande combien de temps il faut pour effectuer 1 000 événements de sumil à 1 ms chacun. J'ai 1034ms. Encore une fois, près de 1ms.

C’était sur un core2duo + Win7 de 1.8ghz avec .Net 4.0

Edit: rappelez-vous, dormir (x) ne signifie pas se réveiller à cette heure, mais me réveiller au plus tôt. Ce n'est pas garanti. Cependant, vous pouvez augmenter la priorité du thread et Windows doit planifier votre thread avant les threads de priorité inférieure.

Non, tous les processeurs disponibles ne seront pas pris en charge, car un thread en veille sera déconnecté par le planificateur du système d’exploitation lorsqu’un autre thread aura du travail à faire.

Non, ça ne va pas. Vous allez à peine le voir. Quelque part moins de 1000 fois par seconde, ce fil se réveille et ne fait presque rien avant de dormir à nouveau.

Modifier:

Je devais vérifier. Sous Java 1.5, ce test

 @Test public void testSpeed() throws InterruptedException { long currentTime = System.currentTimeMillis(); int i = 0; while (i < 1000) { Thread.sleep(1); i++; } System.out.println("Executed in " + (System.currentTimeMillis() - currentTime)); } 

A couru environ 500 dors par seconde sur ma machine de 3 GHz. Je suppose que C # devrait être à peu près le même. Je suppose que quelqu'un rendra compte avec les numéros C # de cette référence extrêmement importante dans le monde réel. Soit dit en passant, aucune utilisation de la CPU n’a été constatée.

Un thread peut tout au plus monopoliser un processeur (logique) à la fois. Et un sumil de 1ms ne sera pas accablant. Ne pas transpirer.

regardez aussi ceci: forum msdn

 using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; namespace Test { public static class Program { public static void Main(ssortingng[] args) { Stopwatch sw = new Stopwatch(); for (int i = 0; i < 10; ++i) { sw.Reset(); sw.Start(); Thread.Sleep(50); sw.Stop(); Console.WriteLine("(default) Slept for " + sw.ElapsedMilliseconds); TimeBeginPeriod(1); sw.Reset(); sw.Start(); Thread.Sleep(50); sw.Stop(); TimeEndPeriod(1); Console.WriteLine("(highres) Slept for " + sw.ElapsedMilliseconds + "\n"); } } [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); } }