2011-04-14 43 views
3

我,直到條件變量設置爲true執行無限循環C#類。還有另一個類等待網絡消息,當接收到消息時,會調用另一個類來將條件變量修改爲true,以便它可以退出while循環。對於該消息的等待是在一個單獨的線程中完成:修改從另一個線程類屬性在C#

Modifier類:

public class Modifier{ 
Otherclass log; 
private static NetworkStream theStream; 
private StreamReader theInput; 

public Modifier(Otherclass other, NetworkStream str) 
      { 
       this.log = other; 
       theStream = str; 
       theInput = new StreamReader(theStream); 
       Thread listenThread = new Thread(new ThreadStart(listen)); 
       listenThread.Start(); 
      } 

      public void listen() 
      { 
       while (true) 
       { 
        log.postMessage(theInput.ReadLine()); 
       } 
      } 
} 

而其他類:

public class Otherclass{ 
    bool docontinue = true; 
    public void postMessage(string input) 
    { 
     docontinue = true; 
    } 

    public void wait() 
    { 
      while(!docontinue) 
      { 
      } 
    } 
} 

的問題是,該方案被卡住的,而(!docontinue)雖然發送了一條消息。我懷疑問題是變量docontinue沒有被修改,但我不知道問題是否在其他地方。

回答

7

有各種各樣的問題,在這裏 -

第一,並直接回答你的問題,是你需要聲明的布爾字段使用volatile

private volatile bool doContinue = true; 

話雖這麼說,有循環,它沒有身體while循環非常不好 - 它會佔用100%的CPU上線了,只是「旋轉」下去。

一個更好的,以這樣的情況的方法是用WaitHandle的更換while循環,如ManualResetEvent。這允許您等待重置事件,並阻止直到您準備好繼續。您在另一個線程中調用Set()以允許執行繼續。

例如,試試這個:

public class Otherclass{ 
    ManualResetEvent mre = new ManualResetEvent(false); 

    public void PostMessage(string input) 
    { 
     // Other stuff here... 
     mre.Set(); // Allow the "wait" to continue 
    }  

    public void Wait() 
    { 
      mre.WaitOne(); // Blocks until the set above 
    } 
} 
0

嘗試增加了Thread.Sleep(100)。也考慮使用ManualResetEvent類。

更新:我剛剛檢查,等待()退出,即使沒有了Thread.Sleep,揮發性和其他東西。但是,我的測試控制檯應用程序掛起,因爲聽()THEAD永遠不會結束......

0

你有兩個(潛在的)無限循環在這裏。並沒有任何實際上稱爲等待()

是否有一個很好的理由,你爲什麼需要在等待方法內的虛擬循環中浪費週期?它的用途是什麼?

在我看來,應該postMessage的揭開序幕,將執行需要的任何工作得到等待後進行()應該打破一個新的線程。

0

其他人都指出,有更好的方法來做到這一點,但我想在您發佈的代碼指出的問題。

public class Otherclass{ 
    bool docontinue = true; 
    public void postMessage(string input) 
    { 
     docontinue = true; 
    } 

    public void wait() 
    { 
      while(!docontinue) 
      { 
      } 
    } 
} 

docontinue不改變數值。它開始爲true,並且在發佈消息時將其設置爲true。最重要的是,你的while子句中沒有,所以循環不應該運行,因爲!docontinue總是爲false。