J'ai mis en place un Pipe
qui utilise en interne une classe BlockingQueue
pour stocker les données qu'il reçoit.
Il existe deux situations dans lesquelles le BlockingQueue
bloquera le thread appelant :
- Le thread appelant fait un appel à
Dequeue()
et la file d'attente est vide. Il bloquera le fil jusqu'à ce qu'il y ait un élément à récupérer. - Le thread appelant fait un appel à
Enqueue()
et la file d'attente est pleine. Il bloquera le thread jusqu'à ce qu'il y ait à nouveau de la place pour insérer les données.
Mon idée initiale était qu'au lieu d'avoir le Pipe
instancie la classe BlockingQueue
je passerais une instance d'un IQueue
par injection de constructeur. De cette façon, lors des tests, je lui passerais une instance d'un fichier NonBlockingQueue
Ainsi, je n'aurais pas à me préoccuper des problèmes de threading (lorsque je fais des tests unitaires, tant pour l'interface utilisateur que pour l'interface utilisateur). Pipe
et pour les autres classes qui utilisent Pipes
J'aimerais simplement ajouter des choses aux files d'attente et ne pas avoir à me demander si elles sont déjà pleines et d'autres choses du genre).
Le problème, c'est qu'en faisant ça, je fais en fait de mon Pipe
se comportent de 2 manières totalement différentes, selon le type de IQueue
instance à laquelle je passe :
-
Dans un
BlockingQueue
si la file d'attente est vide et que vous essayez de récupérer quelque chose, elle va bloquer jusqu'à ce que jusqu'à ce qu'il obtienne quelque chose. Dans uneNonBlockingQueue
il va juste vomir une exception. -
Dans un
BlockingQueue
Si la file d'attente est pleine et que vous essayez d'ajouter quelque chose, elle attendra que quelqu'un retire un élément de la file et qu'il y ait à nouveau de la place. ANonBlockingQueue
va soit faire apparaître unFullQueueException
ou permettra un nombre "infini" d'éléments.
C'est-à-dire qu'il n'y a pas de "contrat unique". Je pense que cette approche est totalement erronée.
Quelle est l'approche la plus appropriée à cet égard ?
Modifier pour Mitch :
Ceci est utilisé pour implémenter un système Pipe&Filter : chaque filtre a un tuyau d'entrée et un tuyau de sortie. Chaque filtre est alors implémenté avec du code de la forme
char c;
while ((c = inputPipe.ReadChar()) != STREAM_TERMINATOR) {
//I don't have to care
//if right now there is any data. I know that if there isn't,
//the thread will block and this will continue after there is some.
...do processing
outputPipe.WriteChar(something);
}
outputPipe.WriteChar(STREAM_TERMINATOR);
donc je suppose que oui, avoir des tuyaux / files d'attente bloquants est le comportement que je veux.