2014-07-26 41 views
2

我明白了在C#中使用的Barrier類。但是,在下面的代碼中,我不明白爲什麼SignalAndWait()被調用兩次?任務中的呼叫不夠嗎?代碼基本上模擬了三個朋友(或任務)從A到B,B到C以及一些從B到A而不會轉到C的情形。 請幫我解決。順便說一句,這段代碼來自於這本書:MCSD Certification Exam Toolkit(70-483)。非常感謝你!屏障類c#

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!"); 
} 

回答

2

您還會看到行Console.WriteLine("{0} paricipants are at rendez-vous point {1}.",...)執行兩次。

單個Barrier實例用於在B和C處渲染。(剩餘的)taks調用SignalAndWait()來標記它們到達B和C兩個調用。

穿着下來代碼:

if (localCopy % 2 == 0) 
    { 
     ... 
     barrier.SignalAndWait();  // arrival at B 
    } 
    else 
    { 
     ... 
     barrier.RemoveParticipant(); // return to A 
     return; 
    } 
    ... 
    barrier.SignalAndWait();   // arrival at C 
+0

感謝亨克。我的問題是,爲什麼在Main方法中有兩個對SignalAndWait的調用? – user3509153

+0

你可以從代碼中知道主線程也是'參與者'。它默默地移動到那裏的狀態A和B.這是一個小技巧,沒有它,你會需要其他構造來使主線程等待其餘的。 –