2014-04-05 32 views
0

我正在做一個服務器,並在客戶端連接,創建一個線程,該監聽來自客戶端的消息,所以基本上只是做StreamReader.Readline()
線程這創建了這個線程必須等到answerListener線程終止,但它不會等待。

這是我的代碼
的Thread.join()簡化版,等到線程結束

  Thread answersListener = new Thread(new ThreadStart(StartListeningAnswers)); 
      answersListener.Name = Thread.CurrentThread.Name + "_listener"; 
      answersListener.Start(); 

      while (player.status.Equals(PlayerStatus.Playing)) 
      { 
       CheckOpponentStatus(); 
       Thread.Yield(); 
      } 

      DetermineResult(player.status); 


      answersListener.Join(); 

      RuntimeInfo.Instance.playerList.TryDequeue(out player); 

      player.Input.Close(); 
      player.Input.Dispose(); 
      player.Output.Close(); 
      player.Output.Dispose(); 
      player.Socket.Close(); 

      Console.WriteLine("client " + player.playerID + " disconnected"); 
      player = null; 

一個組成部分,這是StartListeningAnswers()方法做:

  while (player.status.Equals(PlayerStatus.Playing)) 
      { 
       answer = player.Input.ReadLine(); 
       if (answer == null) return; 
      } 

這是一個catch塊在StartListeningAnswers()方法:

 catch (IOException e) 
     { 
      Console.WriteLine(player.playerID + " Connected = " + player.Socket.Connected); 

      Console.WriteLine("ERROR: ReceiveAnswer from " + player.playerID); 
      return;    
     } 

當我跑我的服務器我得到一個異常,同時試圖做ReadLine()StartListeningAnswers()

我在控制檯輸出順序如下:
client 1 disconnected
1 Connected = False
ERROR: ReceiveAnswer from 1

所以我想主要線程不會等待,直到玩家發送一些東西,然後繼續執行並關閉流。

我做錯了什麼?

回答

1

關於你的代碼有一些問題。首先是,你沒有撥打電話Thread.Yield()。而player.status不是線程安全的(http://rbwhitaker.wikidot.com/c-sharp-threading)。

但是主要的問題是player.status永遠不會變成PlayerStatus.Playing以外,所以服務器中的while循環永遠不會被打斷。

我不完全知道的背景和 我建議實行這種方式不一樣,但你可以這樣做:

public void StartListeningAnswers() 
{ 
    try 
    { 

     while (player.status.Equals(PlayerStatus.Playing)) 
     { 
      string answer = player.Input.ReadLine(); 
      if (string.IsNullOrEmpty(answer)) 
       return; 
     } 

    } 
    finally 
    { 
     player.status = PlayerStatus.Stopped; 
    } 
} 
+0

我應該在哪裏有'Thread.Yield()'方法?我以爲'枚舉'是線程安全的(http://msdn.microsoft.com/en-us/library/vstudio/system.enum%28v=vs.100%29.aspx)有兩種方法來更改'播放器。狀態「:第一個在」StartListeningAnswers()「中,第二種方式是」CheckOpponentStatus「我剛剛刪除了這部分代碼,因爲我認爲它與 – Kolia

+2

沒有關係。 Windows將處理threadslices/time。如果你喜歡在線程中等待,你可以看看'ManualResetEvent'。他們將以較少的CPU消耗來處理等待。 –

+0

枚舉不是問題,枚舉是常量(數字),但玩家的變量是。 –