2008-11-19 7 views
1

J'ai une classe de gestionnaire qui produit des tâches pour un pool de threads, et chaque thread est censé faire un rappel une fois qu'ils sont terminés. J'utilise des verrous pour gérer les variables et les champs, ainsi que des signaux pour gérer les communications inter-thread. Ce que je cherche est une façon de quitter le verrou actuel() et d'attendre un signal atomique, quelque chose comme SignalAndWait, mais pour locks().SignalAndWait pour le contexte de verrouillage

Le code ressemble à ceci:

// ... part of the scheduler 
foreach(WorkTask task in worktasks) 
{ 
    lock(_syncObj) 
    { 
     new Job(task, myCallback); // creates a thread 
     instanceCount++; 
     while(instanceCount > _maxConcurrentTasks) 
      _resetEvent.WaitOne(Timeout.Infinite); 
    } 
} 

// .. the callback 

void myCallback() 
{ 
    lock(_syncObj) 
    { 
     instanceCount--; 
     _resetEvent.Set(); 
    } 
} 

Le problème ici est que .WaitOne() ne quitte pas le verrou(), de sorte que tout fil faisant un rappel sera mort-lock. J'ai eu de grands espoirs pour WaitOne (Int32, bool exitContext), mais ce contexte semble être à propos de remoting et de choses plutôt que de synchronisations.

Répondre

3

Y a-t-il une raison pour utiliser les primitives d'événement plutôt que Monitor.Wait/Pulse/PulseAll? Monitor.Wait libère atomiquement le verrou et attend, réacquérir le verrou avant son retour. Voir my threading article pour plus de détails.

+0

Pas d'autre raison que de ne pas connaître Pulse/PulseAll. Merci! –

Questions connexes