AcceptSocket不尊重Thread.Abort请求

我的理解是Thread.Abort应该在被阻塞的线程上引发ThreadAbortException,但是在处理TcpListener.AcceptSocket时似乎不是这种情况。 以下是该问题的最基本说明:

 class Program { static void Main(string[] args) { Thread thread = new Thread(Listen); thread.Start(); Thread.Sleep(1000); // give it a second to get going Console.WriteLine("Aborting listener thread"); thread.Abort(); thread.Join(); Console.WriteLine("Listener thread finished press  to end app."); Console.ReadLine(); } static void Listen() { try { Console.WriteLine("Starting to listen"); TcpListener listener = new TcpListener(IPAddress.Any, 4070); listener.Start(); Socket socket = listener.AcceptSocket(); Console.WriteLine("Connected!"); return; } catch (ThreadAbortException exception) { Console.WriteLine("Abort requested"); } } } 

thread.Abort()调用应该停止AcceptSocket并执行ThreadAbortException处理程序。 但这并不会发生。

交换我的ListenSync的ListenSrap的Listen包装器,它调用BeginAcceptSocket代替:

 static void ListenAsync() { try { ManualResetEvent clientConnected = new ManualResetEvent(false); Console.WriteLine("Starting to listen"); TcpListener listener = new TcpListener(IPAddress.Any, 4070); listener.Start(); clientConnected.Reset(); var iasyncResult = listener.BeginAcceptSocket((ar) => { Socket socket = listener.EndAcceptSocket(ar); Console.WriteLine("Connected!"); clientConnected.Set(); }, null); clientConnected.WaitOne(); return; } catch (ThreadAbortException exception) { Console.WriteLine("Abort requested"); } } 

在这种情况下,它“似乎”工作正常。 线程正在执行WaitOne时捕获ThreadAbortException。 然而,调用BeginAcceptSocket创建的线程仍在运行并且能够接受套接字(我通过使用Telnet打开该端口来validation这一点)

最后,我添加了Listener.Stop作为TheadAbortException处理程序的一部分,并尝试捕获EndAcceptSocket调用(因为套接字由Stop​​处理)

这是启动和停止侦听套接字连接过程的最佳方法吗?

Thread.Abort不会中止正在侦听套接字的线程的原因是因为该线程在listen()内核调用内被阻塞(道德等同)。 当CLR实际执行时,只能由CLR引发ThreadAbortException ,并且在对listen线程的调用期间实际上卡在非托管系统调用中。 一旦对listen的调用返回并且在CLR内部恢复执行,就可以继续线程中止。

我建议不要使用Thread.Abort() 。 如果您决定采用该路线,则可以使用与第二个示例中的技术类似的技术。 但是,如果要关闭线程侦听Listener.Stop() ,最好使用其他方法并调用Listener.Stop()