web-dev-qa-db-fra.com

Est Thread.Sleep (Timeout.Infinite); plus efficace que si (vrai) {}?

J'ai une application console que je voudrais garder ouverte tout le temps tout en écoutant les événements. J'ai testé Thread.Sleep(Timeout.Infinite); et while (true) { } et tous deux permettent de déclencher les événements tout en maintenant l'application console ouverte. Y at-il un que je devrais utiliser sur l'autre? Si le thread est en veille, y a-t-il quelque chose que je ne devrais pas faire, par exemple modifier une collection statique déclarée dans l'étendue de la classe?

22
Lunyx

Je recommanderais d'utiliser une ManualResetEvent (ou une autre WaitHandle) et d'appeler ManualResetEvent.WaitOne .

Cela aura le même effet que de dormir éternellement, sauf que cela vous fournira un moyen propre de quitter de votre "blocage" infini lorsque vous le souhaitez (en appelant Set() de l'événement).

Utiliser while(true) consomme des cycles de la CPU, c'est donc quelque chose à éviter.

y a-t-il quelque chose que je ne devrais pas faire, par exemple modifier une collection statique déclarée dans l'étendue de la classe?

En général non. Puisque votre thread sera bloqué, l'utilisation de données partagées ne devrait poser aucun problème de synchronisation (à condition que les éléments de la collection n'aient pas d'exigences spécifiques, telles que des éléments d'interface utilisateur devant être utilisés sur un thread avec un contexte de synchronisation approprié. .)

28
Reed Copsey

Contrairement à while(true)..., Thread.Sleep n'utilise pas de cycles de processeur. Ainsi, dans ce sens, la veille est plus efficace. En général, l'utilisation de Busy Waiting en dehors de spinlocks est fortement déconseillée.

Si le fil est en train de dormir, y a-t-il quelque chose que je ne devrais pas faire?

Puisque votre fil de discussion est bloqué lors de l'entrée dans Thread.Sleep, tout ce que vous souhaitez faire pour utiliser ses ressources est un jeu équitable.

4
dasblinkenlight

Je pense l'appel

while (true) { ... } 

est intensif en calcul, car le fil ne s'arrête jamais

Thread.Sleep(Timeout.Infinite);

obtient réellement le fil pour dormir avec l'aide des planificateurs natifs du système d'exploitation. Et puis le fil s'arrête réellement, donc je suppose que c'est moins exigeant en calcul.

3
leoismyname

Yes, while(true) consomme du processeur alors que sleep() fonctionne de manière plus intelligente: La fonction sleep() met le contexte d'exécution actuel en veille; il le fait en appelant un appel système pour appeler la fonction de sommeil du noyau qui est atomiquement
(a) règle une minuterie de réveil
(b) marque le processus en cours comme étant en veille
(c) attend que le réveil se déclenche ou qu’une interruption se produise 

Si vous appelez sleep(), la CPU peut effectuer un autre travail. 

C'est l'une des raisons pour lesquelles sleep() est utile. 

Un lien utile - Soyez prudent lorsque vous utilisez Sleep

2
Grijesh Chauhan

L'appel de la méthode Thread.Sleep provoque le blocage immédiat du thread actuel pendant le nombre de millisecondes ou l'intervalle de temps que vous lui transmettez, puis le reste de sa tranche de temps dans un autre thread.

https://msdn.Microsoft.com/en-us/library/tttdef8x(v=vs.110).aspx

0
Alberto