Thread.Abort no parece lanzar una ThreadAbortException debido a AcceptSocket

Estoy llamando a ChannelServer.ListeningThread.Abort en el siguiente hilo, sin embargo, nada parece suceder. Me gustaría ser más específico, pero no puedo pensar en nada más. No parece haber una excepción ThreadAbortException que se lance, y esta excepción debe lanzarse independientemente del oyente de locking (funciona perfectamente en subprocesos que reciben lockings).

EDITAR importante : con un ManualResetEvent.WaitOne lugar de AcceptSocket , como Lyrik ha sugerido para las pruebas, funciona perfectamente. ¿Por qué AcceptSocket bloquea la AcceptSocket ThreadAbortException ?

ENLACE : Este hilo del foro parece discutir el mismo problema, aunque no puedo resolverlo: 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(); 

No estoy seguro de por qué está recibiendo ese error, pero aquí hay un ejemplo simple que funciona:

 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(); 

Así que me funciona … asumí que habías atravesado el depurador y que tu punto de quiebre dentro de la statement catch no fue alcanzado, ¿es correcto?

Nota: es una mala práctica llamar a Abort , en lugar de eso, debe llamar a Interrupt y manejar la ThreadInterruptedException … es mucho más seguro.

Esto funciona, pero es increíblemente descuidado y desperdicia hilo. ¿Podría alguien simplemente indicarme una manera de lanzar una excepción que “AcceptSocket” no detectará automáticamente?

 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(); 

Aquí un método de extensión AcceptSocket2 simple (perdón por la falta de imaginación con respecto al nombre …). Funciona exactamente como el método original 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; } }