2017-07-10 2 views
1

Voici un code simple qui utilise Thread.Sleep pour suspendre l'exécution, et Stopwatch.ElapsedMilliseconds pour trouver combien de temps le thread a réellement dormi.Comportement étrange avec Thread.Sleep dans VB

Dim sw As New Stopwatch() 
Dim elapsed_ms As Integer = 0 

sw.Start() 
While True 
    Threading.Thread.Sleep(10) 
    elapsed_ms = CInt(sw.ElapsedMilliseconds) 
    Debug.WriteLine("Elapsed: " & elapsed_ms & " ms") 
    sw.Restart() 
End While 

Ma question est: de temps en temps, l'impression de débogage dit que 0 ms se sont écoulées. Comment est-ce possible? Je suis conscient que Thread.Sleep (10) n'est pas précis, et qu'il dort normalement pendant plus de 10 ms, mais je pensais qu'il était garanti de dormir au moins 10 ms.

+0

Vérifiez 'Frequency' et' IsHighResolution' sur la 'StopWatch' pour vérifier que vous avez réellement un' StopWatch' avec une minuterie haute résolution dessus. –

+0

La fréquence est 2531513, ce qui (je crois) signifie qu'il devrait être précis à ~ une demi-microseconde. Dans les deux cas, le champ IsHighResolution lit True. – Cobalt

+0

J'ai juste essayé de reproduire ceci en créant un nouveau projet de console vide, et en collant dans votre code. Je ne vois pas de lignes de 0 ms, mais je vois beaucoup de lignes de 9 ms, ce qui ne devrait pas vraiment se produire d'après ce que je comprends. Quel OS utilisez-vous, et est-ce l'intégralité de votre code? –

Répondre

0

J'essaie personnellement d'éviter d'utiliser Thread.Sleep dans mon code pour une variété de raisons, mais les irrégularités que vous voyez est l'une d'entre elles. Donc, au lieu d'appeler Thread.Sleep, je vais calculer un délai d'attente pour l'incrément pour lequel vous auriez dormi, puis utiliser une boucle while qui ne fait rien. Donc, votre boucle principale While ressemblerait à ceci:

While True 
    Dim l_TO As Date = Now.AddMilliseconds(10) 
    While l_TO > Now 
     'Do Nothing, 
     'Sometimes I will put a Thread.Sleep call in here but that's usually if the amount of time being waited is more than seconds. 
     'Mainly because a loop of this nature will chew up more processing power than you would expect. 
     Thread.Sleep(1) 'Probably not need because of the short time that you are forcing the program to wait. 
    End While 
    elapsed_ms = CInt(sw.ElapsedMilliseconds) 
    Debug.WriteLine("Elapsed: " & elapsed_ms & " ms") 
    sw.Restart() 
End While 

Je sais que cela n'explique pas pourquoi vous voyez le comportement bizarre avec Thread.Sleep mais je pense qu'il est important de mentionner que Thread.Sleep a beaucoup d'inconvénients et peuvent être évités assez facilement.

+0

J'aime l'utilisation de Date, mais cette méthode n'utilise-t-elle pas beaucoup plus de puissance de traitement que la méthode sleep et chronomètre? Edit: également, quelle est la valeur généralement affichée par l'impression de débogage? – Cobalt

+0

C'est ce que je pensais avec les commentaires, mais avoir le 'Thread.Sleep (1)' dans la boucle soulagerait beaucoup de problèmes de puissance de traitement. Malheureusement, cela signifie que vous utilisez toujours Thread.Sleep. –

+1

Juste fouetté un test rapide et il semble que je reçois 9-11 ms étant enregistré dans la fenêtre de sortie. Je surveillais également le gestionnaire de tâches et l'utilisation du processeur était enregistrée à 0 pendant toute la durée de l'exécution.Je n'ai vu aucun 0ms être enregistré en dehors de la première ligne de notation mais je crois que c'était un bogue dans mon application de test de 5 minutes. –