2017-03-20 67 views
0

我目前正在C#窗體中製作客戶機/服務器應用程序。該窗口包含日誌(文本區域),命令行(文本區域)和一個按鈕。我在關閉服務器(另一個線程)的時候遇到了問題。停止線程從另一個線程c偵聽TcpClient#

void Server_Thread_Main(object arg) 
    { 
     TcpClient client; 
     Output.Insert_to_LOG_Window("Server initialized at IP: " + IP_ADDR + ":" + PORT); 
     while (true) 
     { 
      client = listener.AcceptTcpClient(); 
      clients.Add(new C_Client(client, Output, client_ID_iter++)); 

      clients[clients.Count - 1].Start(); 
     } 




    } 

我也有類處理命令進入命令行。它被稱爲Task_Menager。每個命令由新的線程中處理的proccesing命令它有這個功能

void Server_Task_CMD(optargs args) 
    { 
     bool if_start = false; 

     foreach(argument arg in args) 
     { 
      switch (arg.Option) 
      { 
       case "-stop": 
        Output.server.Stop_Server(); //<- stopping server 
        break; 
       case "-start": 
        if_start = true; 
        break; 
       case "-IP": 
        Output.server.Set_Server_IP(arg.Value); 
        break; 
       case "-PORT": 
        Output.server.Set_Server_PORT(arg.Value); 
        break; 
       case "-IPP": 
        if (arg.Value.Contains(':') == true) 
         Output.server.Set_Server_Params(arg.Value); 
        else 
         Output.Insert_to_COMMAND_Log("This " + arg.Value + " isn't valid IP:PORT notation!"); 
        break; 
       case "-V": 
       case "-VIEW": 
        Output.server.Display_IP_PORT(); 
        break; 
       default: 
        Output.Insert_to_COMMAND_Log("Not known command: " + arg.Option + " !"); 
        break; 



      } 
      if(if_start==true) 
       Output.server.Initialize_Server(); 

     } 
    } 

而這個功能是

public void Stop_Server() 
    { 
     if (server_thread.IsAlive == true) 
     { 
      Output.Insert_to_LOG_Window("Stopping server..."); 
      server_thread.Interrupt(); 
      if (!server_thread.Join(2000)) 
      { 
       server_thread.Abort(); 
      } 
      Output.Insert_to_COMMAND_Log("Server has been stopped!!!"); 
     } 
     else 
      Output.Insert_to_LOG_Window("Server isn't running right now!"); 



    } 

而且問題是我不知道爲什麼服務器線程不會停止。

回答

0

這不是接近線程的正確方法。目前你的線程可能是粘在listener.AcceptTcpClient

您應該先listener.Stop();
二關閉監聽器,你必須關閉所有客戶端的插座。
第三,除非絕對沒有別的辦法,否則不應該打電話給thread.Abort

所以你應該Stop_Server看起來更像是這樣的:

public void Stop_Server() 
{ 
    listener.Stop(); 
    server_thread.Join(); 
    Output.Insert_to_COMMAND_Log("Server has been stopped!!!"); 
} 

而且在你線程方法包裹while (true)try-catch(SocketException)

瞭解更多here

+0

謝謝,它幫助:)我知道,它停在'client = listener.AcceptTcpClient();',但不知道我可以阻止它從另一個線程。 –