2011-10-16 42 views
2

正如標題所暗示的。 是的,我知道這是horribad使用.abort(),但聽我把話說完強制關閉'流氓'線程如果中止()不起作用

我使用的是2個線程,主線程(我的應用程序)和插座聽線程(熟悉的聲音的人?) 而不是使用異步的.AcceptAsync()調用(tbh,主要原因是我沒有看太多),我有線程掛在socket.Accept(); Ofcourse,當我調用thread.Abort()時,線程不會關閉,因爲它仍然在等待連接,一旦它通過Accept()它會中止就好。

代碼:

void listenserver() 
    { 
     while (run) 
     { 
      fConsole.WriteLine("Waiting for connections.."); 
      connectedsock = mainsock.Accept(); 
      connected = true; 
      fConsole.WriteLine("Got connection from: " + connectedsock.RemoteEndPoint); 

... 和其他地方:

private void button_start_Click(object sender, EventArgs e) 
    { 
     if (!run) 
     { //code ommitted. 
     } 
     else 
     { 
      run = false; 
      listenthread.Join(3000); 
      if (listenthread.IsAlive) 
      { 
       fConsole.WriteLine("Force-closing rogue listen thread"); 
       listenthread.Abort(); 
      } 
      button_start.Text = "Start"; 
      groupBox_settings.Enabled = true; 
     } 

是有保證的線程將結束,不是要的東西,在一個單獨的應用程序的整個事情的任何方式那麼結束呢? 請注意,我確實將thread.IsBackground設置爲true(正如其他論壇主題中所建議的那樣),但它沒有任何區別。

+1

如果您知道'BeginAccept'和'EndAccept'將解決您的問題,爲什麼您繼續尋求一種不涉及這些方法的解決方案? –

+0

因爲我只想要1個連接同時打開。我知道使用async會大量擴展我的代碼,所以我認爲我會盡可能簡單地做到這一點,並像這樣做。猜猜這不是一種可能性,那麼我只會使用acceptasync。 – Alex

回答

1

由於您已經在使用線程,因此您可能只需使用BeginAccept即可。異步代碼並不需要複雜的代碼,因爲你可以使用lambda表達式是這樣的:

var socket = new Socket(...); 

socket.BeginAccept(result => 
{ 
    if (this.abort) 
    { 
     // We should probably use a signal, but either way, this is where we abort. 
     return; 
    } 

    socket.EndAccept(result); 
    // Do your sockety stuff 
}, null); 

即使對於AsyncCallback一個單獨的方法定義,代碼並不複雜。

通過執行異步IO,您的CPU時間也更加高效,因爲在調用BeginAcceptEndAccept之間,該線程可以重新用於其他處理。既然你在等待連接時沒有將它用於任何有意義的事情,那麼舉行一個線程就顯得毫無意義而且效率低下。

+1

似乎是合理的,但你必須保持線程循環,否則程序將退出(因爲在這種情況下它是一個控制檯項目)。或者BeginAccept()是否阻塞了線程?沒有不可解釋的那就是..--無論如何,我將這個標記爲一個好的答案,除了我已經找到了一個殺死套接字的方法,它會拋出一箇中斷的異常,如果你關閉另一個線程中的套接字,如果你處理您可以優雅地關閉線程。 – Alex

+1

你必須保持GUI線程活着,是的。 'BeginAccept'將立即返回。 –