Alternatives à l'utilisation de Thread.Sleep pour attendre
Tout d'abord, je ne suis pas poser la même question que C# - Alternative à enfiler.Le sommeil?ou Alternative à enfiler.Dormir en C#?. Je ne pense pas que je l'utilise mal et ont besoin d'une véritable alternative pour des situations spécifiques.
Pendant un code de l'exécution de l'analyse, j'ai vu un surprenant violation à venir:
Utilisation de Thread.Sleep() est un signe de défaut de conception.
Cette violation entraîne Pierre de Richie article sur exactement pourquoi ce qui constitue une mauvaise conception.
Nous le savons tous la création de threads est cher et le blocage dans les discussions des moyens de contention sur la piscine. Nous savons aussi que chaque thread va allouer un meg de mémoire, donc il devrait avoir une durée de vie courte, blocage sur l'INTERFACE utilisateur est le mal, à l'aide de sommeil pour le calendrier n'est pas fiable, etc etc etc. Ce qui m'amène à mon point de vue, si vous avez vraiment besoin pour effectuer une veille, que devriez-vous utiliser si pas de Fil.Le sommeil?
Pierre cite qu'un zéro sommeil est le seul usage correct de Fil.Sommeil donnant effectivement le fil du timeslice et permettant à d'autres threads du processus. Et puis, encore plus effrayant, c'est que ce n'est qu'une raison de limitations sur la non géré threads et si re-mise en œuvre dans le CLR créer des effets secondaires de l'utilisation de Thread.Dormir dans vos applications. Tous les points sur la commune de la mauvaise utilisation sont, en fait, de bons exemples de mauvaise utilisation.
J'ai les situations suivantes dans le code de production qui utilise des Threads.Dormir avec un certain succès:
- D'attente pour un fichier de verrouillage à être délaissée par le système d'exploitation (capture fichier de verrouillage des problèmes, attendre une secondeessayez à nouveau, lui donner après un certain temps).
- Le meurtre d'un processus et d'attente pour elle de ne pas apparaître dans la liste des processus (kill, vérifiez qu'il n'est pas en cours d'exécution, attendre une secondevérifiez qu'il n'est pas encore en cours d'exécution, la force de la fermeture).
- D'attente pour copier des tampons à chasse d'eau (vérifier la taille du fichier, essayez d'y accéder, attendrevérifiez si la taille a changé).
Sans utiliser de Fil.Dormir dans des situations comme celles-ci, quelles autres options s'offrent à moi? Boucles serrées ont tendance à faire empirer les choses et je ne crois pas que cela rend l'utilisation d'un "défaut de conception", surtout parce que rien n'est sur l'INTERFACE utilisateur et uniquement dans les threads d'arrière-plan. Il est dans la nature de logiciels d'attendre pour d'autres choses dans un environnement multi-thread avec des facteurs externes affectant votre code, vous devez parfois attendre...
source d'informationauteur BrutalDev
Vous devez vous connecter pour publier un commentaire.
La
WaitHandle
type et les types dérivés offrir un événement piloté par le mécanisme pour l'attente que les liens dans le système d'exploitation. Par exemple, lorsque vous avez unTask<T> task
et vous attendez le résultat en accédant àtask.Result
la mise en œuvre interne n'est pas de vote avec desThread.Sleep
des appels entre les deux. C'est à l'aide d'unWaitHandle
-type dérivé de faire de l'attente et de la synchronisation.Parfois une interrogation de base de l'approche est nécessaire, comme dans certains exemples que vous avez donné à votre liste à puce, mais souvent vous peut utiliser un évènement approche axée sur la place. Ce n'est pas que
Thread.Sleep
est toujours mauvais - c'est juste que c'est très souvent utilisé à mauvais escient.À attendre est très bien. Pour attendre à des bureaux de est souvent pas (*). Si il n'y a aucune façon vous pouvez utiliser un événementiel d'attendrevous devez généralement s'efforcer de les utiliser.
Je n'ai pas une très bonne idée de exactement ce que c'est que vous demandez, donc je ne m'étendrai pas au-delà de cette. Si vous laissez un commentaire, je peux développer ma réponse.
(*) La raison théorique d'attente des bureaux de est mauvais est comme suit:
Supposons que j'ai un code qui ressemble à ceci:
Begin()
commence une opération.Done()
retourtrue
signifie que l'opération est terminée. Supposons que ce sera le cas après environT
temps. Alors:Done()
)T/D
foisSTART
àSTOP
comprend un attenduD/2
purement en raison de laThread.Sleep
Quelle est la valeur de
D
devriez-vous choisir? Comme vous augmentezD
de la durée prévue formeSTART
àSTOP
augmente de façon linéaire. Que vous diminuezD
l' (lié sur le nombre d'itérations augmente à mesure que1/D
. Ces deux sont mauvais, et de trouver la bonneD
est problématique.Maintenant, comparez cela à un événementiel d'attendre:
Théoriquement parlant, aussi longtemps que
WaitDone()
en quelque sorte comme par magie attend jusqu'à la fin de l'opération, mais pas plus, à la fois les problèmes identifiés dans le d'attente des bureaux de cas ont disparu: ce thread attend exactement la bonne quantité de temps - pas plus, pas moins!Réitérer le moment j'ai commencé avec: en .NET, le
WaitHandle
classe et les types dérivés sont ce que faciliter cette approche.Bien, vous l'avez dit plus. Citant "Nous savons tous la création de threads est cher et le blocage dans les discussions des moyens de contention sur la piscine", de sorte que vous comprendre ce à l'aide d'un pool de threads.
Vous comprenez également que le fait de bloquer le thread d'INTERFACE utilisateur est mauvais.
Regardant le pool de threads modèle nouveau: vous disposez d'un pool de threads, peut-être un par processeur, et ensuite passer à des tâches pour eux. Quel sens cela aurait-il pour l'un de ces fils de bloquer? Si elle n'a pas de travail à faire maintenant, alors il faut simplement procéder à une tâche différente.
Donc, en allant directement à votre question "ce Qui m'amène à mon point de vue, si vous avez vraiment besoin pour effectuer une veille, que devriez-vous utiliser si pas de Fil.Le sommeil?", dans un cadre moderne programme bien conçu, vous n'aurez jamais besoin de le faire, il vous suffit de planifier une tâche pour ce dernier.
Vous devriez penser à des threads dans une piscine, un peu comme les processeurs dans un système, en termes de ressources, qui doivent être communiqués à d'autres personnes lorsqu'il n'est pas nécessaire.
Aller à vos exemples, vous êtes un peu trop impliqué dans l'impératif paradigme de programmation.
En attente sur un mécanisme de synchronisation n'est pas "mauvais".
Dans un de mes projets, j'ai utilisé 2 fils et j'ai eu des problème avec l'INTERFACE utilisateur de congélation thnx pour le Filetage.Dormir ....cela a réglé mon problème: