2010-10-17 62 views
1

我想對隊列進行一些測試,並使用Queue.Synchronized查看當兩個線程將東西放入隊列中時它是如何工作的,以及第三個線程是將它讀出來的。這看起來很簡單,但它不能正常工作,我不知道爲什麼。可能是我的一個愚蠢的錯誤。儘管如此,還有一點。我的隊列行事有趣,任何想法爲什麼?

class Program 
{ 
    public int this1 = 0; 
    static void Main(string[] args) 
    { 
     Tester test1 = new Tester(); 

     Queue myQ = new Queue(); 
     Tester.myQ = Queue.Synchronized(myQ); 
     Thread test1_thread = new Thread(new ThreadStart(test1.test1)); 
     Thread test1_thread2 = new Thread(new ThreadStart(test1.test1)); 

     test1_thread.Start(); 
     test1_thread2.Start(); 

     int i = 0; 
     while (i <= 10) 
     { 

      i++; 
     go_back_here: 
      try 
      { 
       Tester.myQ.Enqueue(40); 
       Console.WriteLine("did it"); 
       int holding = Convert.ToInt32(Tester.myQ.Dequeue()); 
       Console.WriteLine("reading out {0}: {1}", i); 
      } 
      catch 
      { 
       //Console.Write("e"); 
       //goto go_back_here; 
      } 
     } 
     Console.ReadLine(); 
    } 


} 

class Tester 
{ 

    public static Queue myQ; 
    public void test1() 
    { 
     int this1 = 0; 

     while (this1 <= 10) 
     { 
      Console.WriteLine("Doing something {0}", this1); 
      myQ.Enqueue(this1); 
      Console.WriteLine("(peek) {0}", myQ.Dequeue()); 
      this1++; 
     } 

    } 
} 

通過我自己的測試,我發現兩個測試器線程正在將東西加載到隊列中。當我的主循環嘗試將它出隊時,我會收到一個錯誤,說隊列是空的。我把Peeks和Dequeues放在測試線程中,他們能夠在線程中顯示這些東西。因此我添加了「Tester.myQ.Enqueue(40);」,因此我想知道如果我是從主循環訪問錯誤的隊列(OOP不是我的專長,仍在學習它),所以我添加了「Tester.myQ.Enqueue(40);」看看我是否可以在其中插入一些東西。我的peeks/Dequeues沒有顯示它,但是,當我添加「完成」寫入行時,它顯示出來了。我已經運行了這個程序了很多次,並且主循環中的40只出現在測試線程打印出來的Dequeue中,當「did it」在那裏。從來沒有當我評論它。

有人對這個問題有更多的瞭解可以瞭解發生了什麼嗎? (是的,我知道我使用goto是一件可怕的事情,我讓它滑動,因爲這應該是一個簡單的測試)

+0

呃哦,你用了'goto',你是否檢查['rapters?](http://xkcd.com/292):) – 2010-10-17 04:45:26

回答

2

看起來你最初的問題是你的主線程也訪問隊列很快(沒有任何內容,因爲在同一時間開始在其中放入東西的線程)。在從主線程的隊列中讀取數據之前,您需要確保線程已完成工作。您可以通過在循環中調用Thread.JoinThread.Sleep進行等待,同時檢查線程設置的某個全局變量的條件。沒有睡眠或加入的情況下建立一個while循環是不夠的。

此外,您的「偷看」不是真正的偷看,因爲它實際上刪除了該項目。您需要使用Console.WriteLine("(peek) {0}", myQ.Peek());而不是myQ.Dequeue()

+0

嘿,謝謝你的回覆。首先只想說,我知道我的Peek實際上並不是一瞥。它最初是,但是後來我把它改成了Dequeue,以確保它可以讓一個對象出列。當我改變它的時候,我離開了Console.WriteLine(「(偷看)」),完全沒有懶惰。 – cost 2010-10-17 04:01:29

+0

哎呀,沒有意識到打進會發布。我不確定您的解決方案是否可以正常工作。我的初始版本的程序在10次迭代後沒有停止主循環,如果嘗試失敗,它將使用goto跳過i ++計數器。該程序會將所有內容放入隊列中,然後它會一直運行,不斷嘗試將隊列出隊,但它不會工作。無盡循環 – cost 2010-10-17 04:03:46

+0

哈哈,看看這個「Console.WriteLine(」讀出{0}:{1}「,i);」東西看起來不對?我忘了把它打印出來的第二個變量,我認爲這是把它搞砸了......似乎工作,或者至少比以前好多了。感謝您的幫助,但非常感謝。我在那裏插入了一個Thread.Sleep,它可以讓我的處理器在循環時避免使用它。 – cost 2010-10-17 04:28:13

相關問題