Existe-t-il un équivalent de Monitor.Pulse
et Monitor.Wait
que je peux utiliser conjointement avec un ReaderWriterLockSlim
?ReaderWriterLockSlim et Pulse/Wait
J'ai une classe où j'ai encapsulé l'accès multi-thread à une file d'attente sous-jacente. Pour mettre en file d'attente quelque chose, j'obtiens un verrou qui protège la file d'attente sous-jacente (et quelques autres objets) puis ajoute l'objet et Monitor.Pulse
l'objet verrouillé pour signaler que quelque chose a été ajouté à la file d'attente. À l'autre extrémité de la file d'attente, j'ai un seul thread d'arrière-plan qui traite les messages en continu lorsqu'ils arrivent dans la file d'attente. Il utilise Monitor.Wait
lorsqu'il n'y a aucun élément dans la file d'attente, pour éviter une interrogation inutile. (Je considère cela comme un bon design, mais les flammes (raison) sont les bienvenus si elles me aider à apprendre autrement.)
private void DequeueForProcessing(object state)
{
while (true)
{
ITask task;
lock (mutex)
{
while (underlying.Count == 0)
{
Monitor.Wait(mutex);
}
task = underlying.Dequeue();
}
Process(task);
}
}
Comme plus d'opérations sont ajoutées à cette classe (nécessitant un accès en lecture seule à la serrure sous-jacent protégé), quelqu'un a suggéré d'utiliser ReaderWriterLockSlim
. Je n'ai jamais utilisé la classe auparavant, et en supposant qu'elle puisse offrir des avantages de performance, je ne suis pas contre, mais seulement si je peux garder le design Pulse/Wait.
Pour les commentaires ... Je ne supposerais pas personnellement que se réveiller de «Wait» signifie «il y a des données»; Je frapperais 'continuer;' et vérifier encore. Cette approche facilite l'ajout d'une installation d'arrêt/de vidange plus tard. Vous pourriez également vouloir seulement 'Pulse' si vous avez ajouté à une file d'attente précédemment vide; sinon, rien n'attend. –
J'aime l'idée de faire l'impulsion seulement après avoir ajouté un seul élément à la file d'attente. Cependant, j'ai un tas d'autres doutes sur mon code (aussi bien que je devrais, c'est multi-threaded), ainsi que l'efficacité de compter les éléments dans la file d'attente et de comparer cette valeur avec 0 (j'espère que ça ne marche pas une liste liée pour faire le comptage.) Je suppose que je devrais vraiment appeler PulseAll dans le cas où c'est un autre thread d'auteur qui reçoit le pouls unique. – Jono
Je serais d'accord avec le 'PulseAll'. Re the 'Count', voir documentation: http://msdn.microsoft.com/en-us/library/fy0wwyz4.aspx" Récupérer la valeur de cette propriété est une opération O (1). "; ce qui signifie: non, il ne fait pas cela - il connaît le «Count» séparément. –