2009-08-17 3 views
2

J'ai deux ManualResetEvents, que j'utilise pour passer le contrôle entre deux threads. Essentiellement une coroutine. Parce que le coroutine contient des objets jetables (ManualResetEvents sont des poignées d'attente), il devrait être jetable. En outre, il doit disposer ces ManualResetEvents lorsqu'il est éliminé. Mais, comme un seul thread s'exécute à la fois, l'un d'entre eux attend (presque) toujours l'une des poignées.Qu'arrive-t-il aux threads en attente si j'appelle WaitHandle.Dispose()?

Quel est le comportement spécifié si je dispose des deux ManualResetEvents? Le fil d'attente sera-t-il bloqué pour toujours ou mettra-t-il fin à l'attente? Que faire si j'appelle .Set() en premier?

Répondre

0

La mise en œuvre de ManualResetEvents est une mauvaise pratique. Créer une classe de superviseur propriétaire par événement, et utiliser un modèle de compteur (chaque utilisation d'augmentation/diminution du thread) dispose du superviseur lorsque le compteur rencontre 0.

+0

Je sais déjà que les filets sont sûrs à éliminer. Le problème est en train d'effectuer l'élimination. Je dois garantir qu'aucun thread n'est bloqué. –

+0

La manière dont vous éliminez un événement pendant qu'il est utilisé confère un comportement imprévisible sur différentes plates-formes ou un chargement différent du processeur. Mais en appliquant le motif correct, résolvez cette question - ne jetez pas l'événement tant qu'il existe la possibilité qu'il puisse être utilisé. – Dewfy

0

J'ai récemment eu un problème similaire, et j'ai décidé de remplacer les poignées d'attente par un moniteur et le motif d'attente/impulsion décrit par Marc Gravell here et here. Étant donné que la classe de contrôle est entièrement gérée, vous n'avez pas à vous soucier de disposer des ressources. Bien sûr, vous devrez peut-être penser à votre procédure d'arrêt, mais le modèle d'attente/d'impulsion est un peu plus flexible pour ajouter des choses comme un drapeau éteint.

Questions connexes