2010-11-09 285 views
1

我有一個包含form1和program.cs文件的winform應用程序。在program.cs中我初始化form1,除此之外,我有一臺服務器。我的問題是:當我關閉表單時,如何停止線程?這裏是我的Program.cs文件的一部分:停止線程

public void start() 
     { 
      this.tcpListener = new TcpListener(IPAddress.Any, 3000); 
      this.listenThread = new Thread(new ThreadStart(ListenForClients)); 
      this.listenThread.Start(); 
     } 


     private void ListenForClients() 
     { 
      //MessageBox.Show("in thread"); 
      this.tcpListener.Start(); 

      while (true) 
      { 
       //blocks until a client has connected to the server 
       TcpClient client = this.tcpListener.AcceptTcpClient(); 

       //create a thread to handle communication 
       //with connected client 
       sThread a = new sThread(form1, listaThreads); 
       listaThreads.Add(a); 
       Thread clientThread = new Thread(new ParameterizedThreadStart(a.HandleClientComm)); 
       clientThread.Start(client); 
      } 
     } 

回答

3

您可以從另一個線索調用TcpListenerClose()

TcpListener.Close()將簡單地調用Socket.Close()並且這是線程安全的。

我不確定AcceptTcpClient如何反應,但您必須檢查。至少它會以正常的方式停止你的監聽線程。

所以,你這樣做:

tcpListener.Close(); 
listenThread.Join(); 

這將很好地關閉線程。

+0

tcpListener.Close();不存在。我發現tcpListener.Close(); AcceptTcpClient給出以下錯誤:阻塞操作被WSACancelBlockingCall調用中斷 – Alex 2010-11-09 09:23:23

+1

我相信'WSACancelBlockingCall'是在這裏終止阻塞調用的正確方法。您應該將該異常視爲關閉該線程的觸發器。我首先要用'BeginAcceptTcpClient'回答,但這是您在不使用異步版本的調用時終止線程的方式。 – 2010-11-09 09:30:12

+0

我解決了它:使用此代碼:嘗試 { client = this.tcpListener。AcceptTcpClient(); } catch { break; } – Alex 2010-11-09 10:35:10

3

而不是主動放棄他們,你應該發信號給他們,他們應該停止,讓他們停止在自己的時間。如果您使用任何BackgroundWorker s,則可以使用CancelAsync方法。對於像在你的例子中手動創建的線程,你可以使用線程必須偶爾檢查的布爾標誌(使用適當的同步)。當你的程序即將關閉設置標誌。避免在線程中調用阻塞方法 - 使用異步方法而不是AcceptTcpClient而不是BeginAcceptTcpClient

如果您正在使用(或可以升級到).NET 4,那麼您還應該考慮使用Task Parallel Library,其中任務爲cancellable

+0

他沒有使用BG工作者 – 2010-11-09 08:29:17

+0

@Liviu M .:你怎麼知道的?他沒有發佈他的所有代碼。 – 2010-11-09 08:30:09

+0

我認爲現有的代碼相當明顯:)也許Alexnadru可以證實它。 – 2010-11-09 08:32:02

0

在運行異步的方法中,您應該檢查一個布爾標誌,如cancel,當您想要停止線程時,您從外部設置爲true。

public bool cancel = false; 

public void MethodRuningOnThread() 
{ 
    while(!cancel) 
    { 
     //do stuff 
    } 
} 

建議不要使用Thread.Abort()方法。

+0

我同意你的看法,但是我擔心在我改變那個標誌之前,我的程序會被阻塞在sr.readLine()中。 – Alex 2010-11-09 09:25:19