由于AcceptSocket,Thread.Abort似乎没有抛出ThreadAbortException

我在下面的线程上调用ChannelServer.ListeningThread.Abort ,但似乎没有任何事情发生。 我想更具体一点,但我想不出更多。 似乎没有抛出ThreadAbortException ,并且无论阻塞侦听器如何都应抛出此exception(它在阻塞接收的线程上完美运行)。

重要编辑 :使用ManualResetEvent.WaitOne而不是AcceptSocket ,正如Lyrik建议进行测试一样,它完美无缺。 为什么AcceptSocket阻止ThreadAbortException

链接 :这个论坛主题似乎讨论了同样的问题,虽然我无法解决任何问题: http : //www.tek-tips.com/viewthread.cfm?qid = 319436&page = 413

 ChannelServer.ListeningThread = new Thread(new ThreadStart(delegate() { Log.Inform("Waiting for clients on thread {0}.", Thread.CurrentThread.ManagedThreadId); while (true) { try { new Thread(new ParameterizedThreadStart(ChannelClientHandler.Initialize)).Start(ChannelServer.Listener.AcceptSocket()); } catch (ThreadAbortException) { Log.Inform("Aborted client listening thread {0}.", Thread.CurrentThread.ManagedThreadId); break; } } })); ChannelServer.ListeningThread.Start(); 

我不确定你为什么会收到这个错误,但这是一个简单的例子:

 ManualResetEvent mrse = new ManualResetEvent(false); Thread test = new Thread(() => { while (true) { try { mrse.WaitOne(); } catch (ThreadAbortException) { Console.WriteLine("No problem here..."); } } }); test.IsBackground = true; test.Start(); Thread.Sleep(1000); test.Abort(); Console.ReadKey(); 

所以它适用于我…我假设你已经通过调试器并且你的catch语句中的断点没有被击中,这是正确的吗?

注意:调用Abort是不好的做法,而应该调用Interrupt并处理ThreadInterruptedException …它更安全。

这是有效的,但它令人难以置信的草率和线程浪费。 任何人都可以指出一种方法来抛出“AcceptSocket”不会自动捕获的exception吗?

 ChannelServer.ListeningThread = new Thread(new ThreadStart(delegate() { Log.Inform("Waiting for clients on thread {0}.", Thread.CurrentThread.ManagedThreadId); while (true) { try { ChannelServer.ClientConnected.Reset(); ChannelServer.Listener.BeginAcceptSocket(new AsyncCallback(ChannelClientHandler.EndAcceptSocket), ChannelServer.Listener); ChannelServer.ClientConnected.WaitOne(); } catch (ThreadInterruptedException) { Log.Inform("Interrupted client listening thread {0}.", Thread.CurrentThread.ManagedThreadId); break; } } })); ChannelServer.ListeningThread.Start(); 

这里有一个简单的AcceptSocket2扩展方法(对于名称缺乏想象力而感到遗憾……)。 它与原始的AcceptSocket方法完全一样。

 using System; using System.Net.Sockets; using System.Threading; ///  /// Extensions to TcpListener ///  public static class TcpListenerExtensions { ///  /// Accepts a pending connection request. ///  /// The TCP listener. ///  /// A  used to send and receive data. ///  /// The listener has not been started with a call to . ///  public static Socket AcceptSocket2(this TcpListener tcpListener) { Socket socket = null; var clientConnected = new ManualResetEvent(false); clientConnected.Reset(); tcpListener.BeginAcceptSocket(delegate(IAsyncResult asyncResult) { try { socket = tcpListener.EndAcceptSocket(asyncResult); } catch (ObjectDisposedException) { } clientConnected.Set(); }, null); clientConnected.WaitOne(); return socket; } }