System.Collections.Concurrent possède de nouvelles collections qui fonctionnent très bien dans les environnements multithread. Cependant, ils sont un peu limités. Soit ils bloquent jusqu'à ce qu'un élément devienne disponible, soit ils renvoient default(T)
(méthodes TryXXX).Collecte simultanée non bloquante?
J'ai besoin d'une collection thread-safe, mais au lieu de bloquer le thread appelant, elle utilise un rappel pour m'informer qu'au moins un élément est disponible.
Ma solution actuelle consiste à utiliser un BlockingCollection, mais d'utiliser l'APM avec un délégué pour obtenir l'élément suivant. En d'autres termes, je crée un délégué à une méthode Take
s de la collection et exécute ce délégué en utilisant BeginInvoke
.
Malheureusement, je dois garder beaucoup d'état dans ma classe pour y arriver. Pire, la classe n'est pas sûre pour les threads; il ne peut être utilisé que par un seul thread. Je suis en train de contourner la limite de la maintenabilité, ce que je préférerais ne pas faire. Je sais qu'il y a quelques bibliothèques qui rendent ce que je fais ici assez simple (je crois que le Reactive Framework en fait partie), mais je voudrais accomplir mes objectifs sans ajouter de références en dehors de la version 4 du cadre.
Y a-t-il de meilleurs modèles que je peux utiliser et qui ne nécessitent pas de références externes pour atteindre mon objectif?
tl; dr:
Y at-il des modèles qui répondent à l'exigence:
« Je dois signaler une collection que je suis prêt pour le prochain élément, et avoir la collection exécuter un rappel lorsque l'élément suivant est arrivé, sans qu'aucun thread ne soit bloqué. "
Est-ce que ce sera thread-safe? Qu'est-ce qui empêche l'élément disponible de devenir indisponible avant l'appel du délégué? Et quel est votre objectif global (c.-à-d. Un système de file d'attente)? –
@Adam Bon point sur la consommation de l'article. Le délégué prend l'article retiré de la collection. Ainsi, l'exécution du délégué est bloquée jusqu'à ce qu'un élément soit 'Take'-en de la collection, et que cet objet soit le' object' passé à EndInvoke. L'objectif global est un peu compliqué; Essentiellement, je dois désactiver un flux de travail jusqu'à ce que l'élément devienne disponible. Vous ne pouvez pas bloquer l'exécution du flux de travail, donc simplement «Prendre» un élément ne fonctionnera pas comme l'appel bloque. Je dois créer un signet, puis passer à une extension. L'extension appelle le délégué, en reprenant le signet dans le rappel. – Will
malheureusement j'ai peu d'expérience avec les flux de travail - essayez d'ajouter que des détails à votre question et il pourrait susciter l'intérêt de quelqu'un :-) –