Pour afficher l’article en anglais, activez la case d’option Anglais. Vous pouvez aussi afficher la version anglaise dans une fenêtre contextuelle en faisant glisser le pointeur de la souris sur le texte.
Traduction
Anglais

Barrier (.NET Framework)

.NET Framework (current version)
 

Un cloisonnement est une primitive de synchronisation définie par l'utilisateur qui permet à plusieurs threads (appelés participants) de travailler simultanément sur un algorithme en plusieurs phases. Chaque participant s'exécute jusqu'à ce qu'il atteigne le point de cloisonnement dans le code. Le cloisonnement représente la fin d'une phase de travail. Quand un participant atteint le cloisonnement, il se bloque jusqu'à ce que tous les participants aient atteint le même cloisonnement. Une fois que tous les participants ont atteint le cloisonnement, vous pouvez éventuellement appeler une action post-phase. Cette action post-phase peut être utilisée pour effectuer des actions avec un thread unique alors que tous les autres threads sont encore bloqués. Une fois l'action exécutée, tous les participants sont débloqués.

L'extrait de code suivant montre un modèle de cloisonnement de base.


 // Create the Barrier object, and supply a post-phase delegate 
 // to be invoked at the end of each phase.
 Barrier barrier = new Barrier(2, (bar) => 
     {
         // Examine results from all threads, determine 
         // whether to continue, create inputs for next phase, etc. 
         if (someCondition)
             success = true;
     });       


 // Define the work that each thread will perform. (Threads do not
 // have to all execute the same method.)
 void CrunchNumbers(int partitionNum)
 {
     // Up to System.Int64.MaxValue phases are supported. We assume
     // in this code that the problem will be solved before that.
     while (success == false)
     {
         // Begin phase:
         // Process data here on each thread, and optionally
         // store results, for example:
         results[partitionNum] = ProcessData(data[partitionNum]);

         // End phase:
         // After all threads arrive,post-phase delegate
         // is invoked, then threads are unblocked. Overloads
         // accept a timeout value and/or CancellationToken.
         barrier.SignalAndWait();
     }
 }

 // Perform n tasks to run in in parallel. For simplicity
// all threads execute the same method in this example.
 static void Main()
 {
     var app = new BarrierDemo();
     Thread t1 = new Thread(() => app.CrunchNumbers(0));
     Thread t2 = new Thread(() => app.CrunchNumbers(1));
     t1.Start();
     t2.Start();

 }

Pour obtenir un exemple complet, voir How to: Synchronize Concurrent Operations with a Barrier.

Quand vous créez un Barrier, spécifiez le nombre de participants. Vous pouvez également ajouter ou supprimer des participants dynamiquement à tout moment. Par exemple, si un participant résout sa part du problème, vous pouvez stocker le résultat, arrêter l'exécution sur ce thread et appeler RemoveParticipant pour décrémenter le nombre de participants du cloisonnement. Quand vous ajoutez un participant en appelant AddParticipant, la valeur de retour spécifie le numéro de la phase actuelle, ce qui peut être utile pour initialiser le travail du nouveau participant.

Des blocages peuvent se produire si un participant ne parvient pas à atteindre le cloisonnement. Pour éviter ces blocages, utilisez les surcharges de la méthode SignalAndWait pour spécifier un délai d'attente et un jeton d'annulation. Ces surcharges retournent une valeur booléenne que chaque participant peut vérifier avant de passer à la phase suivante.

Si le délégué post-phase lève une exception, il est encapsulé dans un objet BarrierPostPhaseException qui est ensuite propagé à tous les participants.

Les cloisonnements sont particulièrement utiles quand les threads exécutent plusieurs phases dans des boucles. Si votre code requiert uniquement une ou deux phases de travail, songez à utiliser des objets System.Threading.Tasks.Task avec n'importe quel type de jointure implicite, notamment :

Pour plus d'informations, voir Chaining Tasks by Using Continuation Tasks.

Afficher: