Comment faire pour bloquer une opération jusqu'à ce qu'une condition est remplie?
Je suis en cours d'exécution du présent code et c'est à l'aide d'une bonne quantité de CPU, même si elle est en train de faire rien-absolument rien la plupart du temps.
while (this.IsListening)
{
while (this.RecievedMessageBuffer.Count > 0)
{
lock (this.RecievedMessageBuffer)
{
this.RecievedMessageBuffer[0].Reconstruct();
this.RecievedMessageBuffer[0].HandleMessage(messageHandler);
this.RecievedMessageBuffer.RemoveAt(0);
}
}
}
Quelle est la meilleure façon de bloquer jusqu'à ce qu'une condition est remplie?
Thread.Sleep()
?- Fil de discussion.Sleep() bloque l'INTERFACE utilisateur ainsi.
- non, c'est presque toujours la bonne réponse. Il y a des structures dédiées à cette tâche, comme le WaitHandle proposé par la Marque. Voir stackoverflow.com/questions/9417260/...
- J'ai édité ton titre. Se reporter à la rubrique "si vous avez des questions comprennent “tags” dans leurs titres?", où le consensus est "non, ils ne devraient pas".
Vous devez vous connecter pour publier un commentaire.
En supposant que vous utilisez .NET 4, je vous suggère de commutation
RecievedMessageBuffer
être un BlockingCollection. Lorsque vous mettez des messages en elle, l'appeler à l' Ajouter méthode. Lorsque vous souhaitez récupérer un message, appel, c'est Prendre ou TryTake méthodes. Va bloquer le thread de lecture jusqu'à ce qu'un message est disponible, sans brûler les CPU comme votre exemple original.Utiliser un
WaitHandle
.Vous pourriez aussi envisager de changer l'interface de votre classe pour déclencher un événement quand il y a de nouvelles données à lire. Ensuite, vous pouvez mettre votre code dans le gestionnaire d'événement.
WaitHandle
avecSet()
méthode. Je pense qu'il devrait être au moinsEventWaitHandle
à la place.Au-dessus de lignes de code et plus précisément AutoResetEvent est disponible dans la version 3.5. Si simple code comme ci-dessus avec quelques correction mineure est très efficace parce qu'il fonctionne et à proximité de la fondation de l'API. La correction devrait être
AutoResetEvent waitHandle = new AutoResetEvent(false);
Constructeur avec argument fallacieux fait WaitOne() pour attendre parce que AutoResetEven n'est pas à zéro (faux). Il n'y a pas beaucoup d'avantage de l'utilisation de l'interface WaitHandle, donc, je voudrais juste utiliser AutoResetEvent au lieu qu'elle expose la méthode de Jeu et WaitOne est assez détaillé dans ce cas. Plus important encore, l'argument du constructeur et doit être fausse.