C#學習筆記(1):中斷被Socket.Accept阻塞的執行緒
阿新 • • 發佈:2019-01-04
剛剛學習C#,在編寫一個網路通訊的程式的時候,遇到了點麻煩。監聽程式碼是放在一個執行緒中,當線上程中呼叫Socket.Accept()函式時,倘若這時需要中止該執行緒,C#似乎沒有提供現成的辦法,使用了Thread.Abort()和Thread.Interrupt()函式,都沒有用。有人說用非同步Accept方法避免阻塞,可是用這種方法就得線上程中不停地輪詢Socket的狀態,會導致CPU負荷增加。還有人提出可以現在程式內部建立一個對偵聽Socket的連線,然後傳送特定的推出資料序列,當監聽程式收到這個特殊序列後就主動結束執行緒。這個方法雖然可以解決問題,但是未免複雜了些。
建立執行緒的程式碼如下:
中止執行緒的程式碼如下:
呼叫執行緒類的stop函式之後,會將處於監聽遠端連線的listenSocket關閉掉,這時會導致引發System.Net.Sockets.SocketException,線上程程式碼中捕獲並處理這個異常就行了。這種方法實現簡單,也不會產生額外的CPU資源。
想來想去,突然想到如果將監聽socket關閉掉,引發socket異常,然後在監聽執行緒中捕獲這個異常不就可以中止監聽執行緒了嗎,試驗了一下,果然可以。監聽執行緒的程式碼如下:
using System; using System.IO; using System.Net.Sockets; using System.Net; public class ListenThread { public void run() { Console.Write("creating listen socket ..."); listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listenSocket.Bind(new IPEndPoint(IPAddress.Any, 65365)); listenSocket.Listen(0); Console.Write(" done.\n"); try { Console.Write("listening ..."); ioSocket = listenSocket.Accept(); Console.Write(" accepted.\n"); Console.Write("creating I/O thread ..."); // new Thread(new ThreadStart(this.networkIOThreadProc)).Start(); Console.Write(" done.\n"); } catch (Exception e) { Console.WriteLine("Thread aborted."); } finally { Console.WriteLine("Thread resource released."); } } public void stop() { if (listenSocket != null) { listenSocket.Close(); } } private Socket listenSocket = null; private Socket ioSocket = null; }
建立執行緒的程式碼如下:
ListenThread listener = new ListenThread();
Thread listenThread = new Thread(new ThreadStart(listener.run));
listenThread.Start();
中止執行緒的程式碼如下:
listener.stop();
呼叫執行緒類的stop函式之後,會將處於監聽遠端連線的listenSocket關閉掉,這時會導致引發System.Net.Sockets.SocketException,線上程程式碼中捕獲並處理這個異常就行了。這種方法實現簡單,也不會產生額外的CPU資源。