I do understand about Barrier
class used in C#. However, in the code below, I don't understand why the SignalAndWait()
has been called twice? Isn't the call in the task enough? The code basically models the situation wherein three friends (or Tasks) travel from A to B, B to C, and some go back from B to A without going to C.
Please help me out. By the way, this code is from the book: MCSD Certification Exam Toolkit
(70-483). Thank you very much!
static void Main(string[] args)
{
var participants = 5;
Barrier barrier = new Barrier(participants + 1,
b => { // This method is only called when all the paricipants arrived.
Console.WriteLine("{0} paricipants are at rendez-vous point {1}.",
b.ParticipantCount -1, // We substract the main thread.
b.CurrentPhaseNumber);
});
for (int i = 0; i < participants; i++)
{
var localCopy = i;
Task.Run(() => {
Console.WriteLine("Task {0} left point A!", localCopy);
Thread.Sleep(1000 * localCopy + 1); // Do some "work"
if (localCopy % 2 == 0) {
Console.WriteLine("Task {0} arrived at point B!", localCopy);
barrier.SignalAndWait();
}
else
{
Console.WriteLine("Task {0} changed its mind and went back!", localCopy);
barrier.RemoveParticipant();
return;
}
Thread.Sleep(1000 * (participants - localCopy)); // Do some "morework"
Console.WriteLine("Task {0} arrived at point C!", localCopy);
barrier.SignalAndWait();
});
}
Console.WriteLine("Main thread is waiting for {0} tasks!",
barrier.ParticipantCount - 1);
barrier.SignalAndWait(); // Waiting at the first phase
barrier.SignalAndWait(); // Waiting at the second phase
Console.WriteLine("Main thread is done!");
}
You will also see the line Console.WriteLine("{0} paricipants are at rendez-vous point {1}.",...)
execute twice.
The single Barrier instance is used to rendez-vous at both B and at C. The (remaining) taks call SignalAndWait()
to mark their arrival at both B and C, thus two calls.
Dressed down code:
if (localCopy % 2 == 0)
{
...
barrier.SignalAndWait(); // arrival at B
}
else
{
...
barrier.RemoveParticipant(); // return to A
return;
}
...
barrier.SignalAndWait(); // arrival at C