2013-05-13 28 views
0

我正在查看本網站的threads。 我一直在玩代碼來回答問題「CountdownEvent是否停止所有線程?」 我得到的答案是否定的。然後我決定玩傳入CountdownEvent的數字。這裏是我的代碼CountDownEvent不會等到所有信號都被調用

namespace ThreadPractice 
{ 
    class Program 
    { 
     static CountdownEvent CountDown = new CountdownEvent(4); 
     static void Main() 
     { 
      new Thread(() => SaySomething("I am Thread one.")).Start(); 
      new Thread(() => SaySomething("I am thread two.")).Start(); 
      new Thread(() => SaySomethingElse("Hello From a different Thread")).Start(); 
      new Thread(() => SaySomething("I am Thread Three.")).Start(); 
      CountDown.Wait(); 
      Console.Read(); 
     } 

     static void SaySomething(string Something) 
     { 
      Thread.Sleep(1000); 
      Console.WriteLine(Something); 
      CountDown.Signal(); 
     } 

     static void SaySomethingElse(string SomethingElse) 
     { 
      Thread.Sleep(1000); 
      Console.WriteLine(SomethingElse); 
     } 
    } 
} 

我期待的是調用SaySomethingELse線程()來執行,但其他線程執行,同時即使只有四個信號已被調用。

它爲什麼這樣做?

感謝,

dhoehna

+1

爲什麼你會想到其他線程*不*執行?只有你的主線程正在使用'Wait'。其他人只是*信號*倒數。 – 2013-05-13 19:56:31

+1

我期望所有的線程運行並打印一些內容,然後讓程序在CountDown.Wait()調用中永遠阻塞。倒計時的目的是阻止*一個線程*直到其他一些線程發出信號表示繼續安全。 – dlev 2013-05-13 19:57:03

+0

@dlev什麼是錯誤的是,我忘了在所有的線程上等待。我認爲等待是一個全面的陳述。 – 2013-05-14 14:48:12

回答

3

它看起來像你對我已經有了SignalWait以錯誤的方式。如果您希望SaySomething調用等待倒數到達0,則應該調用Wait。這裏有一個例子:

using System; 
using System.Threading; 

namespace ThreadPractice 
{ 
    class Program 
    { 
     static CountdownEvent CountDown = new CountdownEvent(4); 
     static void Main() 
     { 
      new Thread(() => SaySomething("I am Thread one.")).Start(); 
      new Thread(() => SaySomething("I am thread two.")).Start(); 
      new Thread(() => SaySomethingElse("Hello From a different Thread")).Start(); 
      new Thread(() => SaySomething("I am Thread Three.")).Start(); 
      for (int i = 0; i < 4; i++) 
      { 
       Console.WriteLine("Calling Signal (time #{0})", i); 
       CountDown.Signal(); 
       Thread.Sleep(1000); 
      } 
      Console.WriteLine("Done"); 
     } 

     static void SaySomething(string Something) 
     { 
      CountDown.Wait(); 
      Console.WriteLine(Something); 
     } 

     static void SaySomethingElse(string SomethingElse) 
     { 
      Thread.Sleep(1000); 
      Console.WriteLine(SomethingElse); 
     } 
    } 
} 

輸出:

Calling Signal (time #0) 
Hello From a different Thread 
Calling Signal (time #1) 
Calling Signal (time #2) 
Calling Signal (time #3) 
I am Thread one. 
I am Thread Three. 
I am thread two. 
Done 
+0

我明白。您的for循環在每個線程上調用wait。所以爲了阻止一個關於倒數計時器的線程,我需要在每個線程上調用wait。非常感謝。 – 2013-05-14 14:47:12

1

嗯...它像要等待所有的線程在主線程繼續之前完成在我看來。如果是這樣,你忘記了SaySomethingElse()中的Signal()。這可以防止CountDown.CurrentCount達到0(零),這就是爲什麼你的主線程「卡住」你將它設置爲4,它只能下降到1(一)。修復它,你應該得到所需的?結果:

class Program 
{ 
    static CountdownEvent CountDown = new CountdownEvent(4); 
    static void Main() 
    { 
     new Thread(() => SaySomething("I am Thread one.")).Start(); 
     new Thread(() => SaySomething("I am thread two.")).Start(); 
     new Thread(() => SaySomethingElse("Hello From a different Thread")).Start(); 
     new Thread(() => SaySomething("I am Thread Three.")).Start(); 

     CountDown.Wait(); 

     Console.WriteLine("Done!"); 
     Console.Read(); 
    } 

    static void SaySomething(string Something) 
    { 
     Thread.Sleep(1000); 
     Console.WriteLine(Something); 
     CountDown.Signal(); 
    } 

    static void SaySomethingElse(string SomethingElse) 
    { 
     Thread.Sleep(1000); 
     Console.WriteLine(SomethingElse); 
     CountDown.Signal(); 
    } 
} 

輸出:

I am Thread one. 
I am thread two. 
Hello From a different Thread 
I am Thread Three. 
Done! 
+0

謝謝,但這與我所尋找的是相反的。這不是我想讓線程等待。正是我將倒計時設置爲四次,而且我只使用了三個信號,線程仍然執行。我想知道爲什麼會發生這種情況。我想停止線程執行,因爲我將倒數計時器設置爲4,並且只進行三次信號調用。 – 2013-05-14 14:45:05

+0

實際調用Wait()的線程是暫停的線程。在您的原始代碼中,這是主線程。它完全按照它應該做的,停下來,因爲櫃檯沒有達到零。其他線程只是自己執行的普通線程。調用Signal()不影響它們的運行方式,它只是減少計數。 Jon的例子翻轉了它,並使每個單獨的線程等到計數爲零,而不是主線程在等待。主線程發出足夠多次的信號讓其他線程繼續。很高興你已經把它全部整理出來。 – 2013-05-14 14:59:30

相關問題