2010-09-21 3 views
0

J'utilise le soutien TPL pour mettre en œuvre un modèle multithreading producteur-consommateur en C#. Avec les classes BlockingCollection et Task, le travail est facile, jusqu'à ce que j'ai besoin de gérer les exceptions.Gestion des exceptions dans le modèle producteur-consommateur en utilisant TPL en C#

Comme nous le savons tous, les objets Tâches de consommation seront bloqués quand il n'y a aucun élément dans BlockingCollection pour la consommation et pour éviter les tâches de l'attente à l'infini, il est vital d'appeler BlockingCollection.CompleteAdding() pour indiquer explicitement tout le monde qu'il y Il n'y a plus d'élément à ajouter à BlockingCollection et à réveiller les Tâches en attente.

Dans mon cas, il est possible qu'entre le lancement de plusieurs consommateurs et l'appel de BlockingCollection.CompleteAdding(), il y a une exception jetée. Lorsque l'exception est levée, l'exécution s'arrête, ce qui signifie que BlockingCollection.CompleteAdding() ne sera jamais appelé et que les tâches attendront pour toujours. Et dans mon cas, j'ai un gros gâteau et le producteur-consommateur n'en est qu'une partie alors que l'exception peut être jetée d'autres morceaux du gâteau, ce qui signifie qu'il n'y a pas de moyen facile pour le producteur - le morceau de gâteau du consommateur pour détecter l'exception et pour s'occuper du nettoyage.

Y at-il un modèle utile pour rencontrer une telle situation?

+0

vous avez probablement besoin de partager du code. Si l'exception ne va pas être lancée sur le thread de production, je ne vois aucun problème à appeler CompleteAdding. Et s'il est lancé sur un thread de production, alors votre CompleteAdding peut entrer dans le bloc finally. – VinayC

Répondre

2

Je vous suggère d'utiliser un bloc finally qui appelle CompleteAdding() pour s'assurer que la file d'attente est toujours fermée, même si une exception est levée.