Para ver el artículo en inglés, active la casilla Inglés. También puede ver el texto en inglés en una ventana emergente si pasa el puntero del mouse por el texto.
Traducción
Inglés

Barrier (.NET Framework)

.NET Framework (current version)
 

Una barrera es un primitivo de sincronización definido por el usuario que permite que varios subprocesos (conocidos como participantes) trabajen simultáneamente en un algoritmo por fases. Cada participante se ejecuta hasta que alcanza el punto de barrera en el código. La barrera representa el final de una fase de trabajo. Cuando un participante alcanza la barrera, se bloquea hasta que todos los participantes alcancen la misma barrera. Cuando todos los participantes alcanzan la barrera, opcionalmente puede invocar una acción posterior a la fase. Esta acción posterior a la fase puede usarse para realizar acciones con un solo subproceso mientras todos los demás subprocesos siguen bloqueados. Una vez ejecutada la acción, se desbloquean todos los participantes.

El fragmento de código siguiente muestra un modelo de barrera básico.


 // 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();

 }

Para obtener un ejemplo completo, consulte How to: Synchronize Concurrent Operations with a Barrier.

Cuando cree una Barrier, especifique el número de participantes. También puede agregar o quitar participantes dinámicamente en cualquier momento. Por ejemplo, si un participante resuelve su parte del problema, puede almacenar el resultado, detener la ejecución de ese subproceso y llamar a RemoveParticipant para reducir el número de participantes en la barrera. Cuando se agrega un participante mediante una llamada a AddParticipant, el valor devuelto especifica el número de fase actual, que puede ser útil para inicializar el trabajo del nuevo participante.

Si un participante no consigue alcanzar la barrera, pueden producirse interbloqueos. Para evitar estos interbloqueos, use las sobrecargas del método SignalAndWait para especificar un período de tiempo de espera y un token de cancelación. Estas sobrecargas devuelven un valor booleano que cada participante puede comprobar antes de continuar con la fase siguiente.

Si el delegado posterior a la fase produce una excepción, se encapsula en un objeto BarrierPostPhaseException que después se propaga a todos los participantes.

Las barreras resultan especialmente útiles cuando los subprocesos realizan varias fases en bucles. Si el código solo requiere una o dos fases de trabajo, piense en usar objetos System.Threading.Tasks.Task con cualquier tipo de unión implícita, incluidas:

Para obtener más información, consulte Chaining Tasks by Using Continuation Tasks.

Mostrar: