2009-08-07 9 views
15

J'ai un thread en cours d'exécution qui délègue certaines tâches. Quand une seule tâche est terminée, un événement est levé en disant qu'il est terminé. Ces tâches doivent être exécutées dans un ordre spécifique et doivent attendre la fin de la tâche précédente. Comment puis-je faire attendre le thread jusqu'à ce qu'il reçoive l'événement "task completed"? (Mis à part le gestionnaire d'événement évident qui définit un indicateur, puis une boucle while interrogeant le drapeau)Quelles méthodes peuvent être utilisées pour que le thread attende un événement, puis continue son exécution?

Répondre

27

J'utilise souvent la poignée AutoResetEvent d'attente quand je dois attendre une tâche asynchrone pour terminer:

public void PerformAsyncTasks() 
{ 
    SomeClass someObj = new SomeClass() 
    AutoResetEvent waitHandle = new AutoResetEvent(false); 
    // create and attach event handler for the "Completed" event 
    EventHandler eventHandler = delegate(object sender, EventArgs e) 
    { 
     waitHandle.Set(); // signal that the finished event was raised 
    } 
    someObj.TaskCompleted += eventHandler; 

    // call the async method 
    someObj.PerformFirstTaskAsync();  
    // Wait until the event handler is invoked 
    waitHandle.WaitOne(); 
    // the completed event has been raised, go on with the next one 
    someObj.PerformSecondTaskAsync(); 
    waitHandle.WaitOne(); 
    // ...and so on 
} 
+1

Basé sur la première réponse, je fais quelque chose de très similaire à cela. Quelle est la différence entre AutoResetEvent et EventWaitHandle initialisé avec EventResetMode.AutoReset? – MGSoto

+0

@MGSoto: Je pense que la différence est minime (le cas échéant): 'AutoResetEvent' hérite de' EventWaitHandle', et semble utiliser le constructeur de sa classe de base pour lui passer 'EventResetMode.AutoReset'. –

+2

N'oubliez pas que AutoResetEvent, WaitHandles etc implémente IDisposable –

5

Une option consisterait à utiliser un EventWaitHandle pour signaler l'achèvement.

+0

pourriez-vous élaborer? expliquez-le mieux et je voterai très certainement! – Firoso

+1

+1. @firoso, il y a beaucoup de détails dans l'article msdn. –

+0

Y compris les exemples dans plusieurs langues – bdonlan

1

Vous pouvez utiliser un ManualResetEvent pour cela.

Le thread qui doit traiter en premier prend simplement le resetEvent, et attend la fin de Set the event.

Le thread qui doit attendre peut contenir un handle et appeler resetEvent.WaitOne(). Cela bloquera ce thread jusqu'à la fin du premier.

Cela vous permet de gérer le blocage et la commande des événements d'une manière très propre.

0

J'ai eu de bons résultats en utilisant une méthode de rappel que le thread de travail appelle lorsqu'il est terminé. Il bat l'interrogation et facilite le renvoi des paramètres à l'appelant.

Questions connexes