2016-09-05 79 views
0

我有一個button1的一種形式,這種代碼爲什麼在啓動服務器tcp時,表單消失?

private void button1_Click(object sender, EventArgs e) 
{ 
    ServerTCP s = new ServerTCP(); 
} 

然後是類serverTCP

public ServerTCP() 
{ 
    TcpListener listen = new TcpListener(IPAddress.Any, 1200); 
    Console.WriteLine("Waiting"); 
    listen.Start(); 
    while (true) 
    { 
     TcpClient client = listen.AcceptTcpClient(); 
     Console.WriteLine("Client connected"); 
     NetworkStream stream = client.GetStream(); 
     byte[] buffer = new byte[client.ReceiveBufferSize]; 
     int data = stream.Read(buffer, 0, client.ReceiveBufferSize); 
     string message = Encoding.Unicode.GetString(buffer, 0, data); 
     int idgiorno = Int32.Parse(message); 
     Console.WriteLine("idgiorno: " + idgiorno); 
     client.Close(); 
    } 
} 

的問題是,當我點擊按鈕1,形式消失。我可以從開始欄看到它仍在運行,但即使我點擊它的圖標,它也不會顯示它。這就像表單失去焦點。

+0

對我來說,就像你在你的程序的主線程上運行一個連續的循環,導致崩潰,因此你無法使用它。 – ThePerplexedOne

+0

該程序是一個服務器,不斷等待來自客戶端的輸入。但我需要關注表單,因爲應該有另一個按鈕來關閉應用程序 – Alessandro

+0

然後在與主應用程序分開的線程上運行代碼。您可以瞭解更多關於線程[這裏](https://msdn.microsoft.com/en-us/library/aa645740(v = vs.71).aspx)。 – ThePerplexedOne

回答

0

我可以看到你想要在這裏做什麼,但是即使你修好了這些,恐怕你也會遇到麻煩。

首先,如前所述,你失去你的原因是因爲你在主線程中輸入了一個無限循環。爲避免這種情況,請嘗試使用;

using System.Threading.Tasks 
public ServerTCP() 
{ 
    TcpListener listen = new TcpListener(IPAddress.Any, 1200); 
    Console.WriteLine("Waiting"); 
    listen.Start(); 
    Task myTask = new Task(() => 
    { 
     while (true) 
     { 
      TcpClient client = listen.AcceptTcpClient(); 
      Console.WriteLine("Client connected"); 
      NetworkStream stream = client.GetStream(); 
      byte[] buffer = new byte[client.ReceiveBufferSize]; 
      int data = stream.Read(buffer, 0, client.ReceiveBufferSize); 
      string message = Encoding.Unicode.GetString(buffer, 0, data); 
      int idgiorno = Int32.Parse(message); 
      Console.WriteLine("idgiorno: " + idgiorno); 
      client.Close(); 
     } 
    }); 
    myTask.Start(); 
} 

這是一種懶惰的方式來將任務派發到池中的備用線程,而無需自己創建管理線程。該代表團被稱爲lambda表達式;

https://msdn.microsoft.com/en-GB/library/bb397687.aspx

這樣做的問題是,這個線程將無法訪問控制檯資源無論如何,所以我怕你不會看到你的消息。

在您的代碼中,您已經「程序化」地編寫了所有內容。這意味着您已經編寫了一份指示清單,假定每個步驟都已準備好了補貼。例如;

byte[] buffer = new byte[client.ReceiveBufferSize]; 

如果在這裏你還沒有收到數據,你將嘗試初始化一個0零的緩衝區,世界將結束。

與其試圖通過這一步一步步完成,請觀看這​​兩個YouTube視頻作爲一個很好的介紹。他們並不完美,但應該幫助你進一步前進;

https://www.youtube.com/watch?v=uXFso7xSSWk

https://www.youtube.com/watch?v=NanjpGKC2js

真的,實現你的應用程序的唯一可靠的方法就是通過「事件驅動編程」,但是這可能是一個新的一天。

祝你好運!

0

好了,基本上下面的調用不會返回:

ServerTCP s = new ServerTCP(); 

ServerTcp構造包含一個無限循環,這樣做不僅通話有去無回,而且還阻礙了UI線程。在阻塞的UI線程中,像WM_ACTIVATE或WM_PAINT這樣的窗口消息將永遠不會被處理,因此您將使表單無法使用。

你真的應該考慮異步使用TcpListenerThis is a good starting point。然後您將刪除您的循環,因爲重複呼叫BeginAcceptTcpClient將使您的服務器保持運行。

相關問題