Thread.Abort ne semble pas jeter un ThreadAbortException à cause de AcceptSocket
-
01-10-2019 - |
Question
Je fais appel ChannelServer.ListeningThread.Abort
sur le fil suivant, mais rien ne semble se passer. Je voudrais être plus précis, mais je ne peux pas penser à quelque chose de plus. Il semble y avoir aucune ThreadAbortException
qui est jeté, et cette exception devrait être jeté quel que soit l'auditeur de blocage (cela fonctionne parfaitement sur les threads de réception blockingly).
EDIT Important : Avec un ManualResetEvent.WaitOne
au lieu de AcceptSocket
, comme Lyrik a suggéré pour les tests, cela fonctionne parfaitement. Comment se bloque AcceptSocket
le ThreadAbortException
?
: Ce fil de discussion semble discuter de la même question, bien que je ne peux pas quoi que ce soit hors de lui: 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();
La solution 2
Cela fonctionne, mais il est incroyablement bâclé et le fil-gaspillage. Quelqu'un pourrait-il me montrer juste un moyen de jeter une exception « AcceptSocket » ne sera pas automatiquement attraper?
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();
Autres conseils
Je ne sais pas pourquoi vous obtenez cette erreur, mais voici un exemple simple qui fonctionne:
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();
Alors ça marche pour moi ... Je suppose que vous avez entré dans le débogueur et votre point de rupture dans l'instruction de capture n'a pas été touché, est-ce pas?
Note:. Il est une mauvaise pratique à l'appel Abort
, au lieu vous devez appeler Interrupt
et gérer les ThreadInterruptedException
... il est beaucoup plus sûr
Voici une méthode simple d'extension de AcceptSocket2
(désolé pour le manque d'imagination en ce qui concerne le nom ...).
Il fonctionne exactement comme la méthode AcceptSocket
originale.
using System;
using System.Net.Sockets;
using System.Threading;
/// <summary>
/// Extensions to TcpListener
/// </summary>
public static class TcpListenerExtensions
{
/// <summary>
/// Accepts a pending connection request.
/// </summary>
/// <param name="tcpListener">The TCP listener.</param>
/// <returns>
/// A <see cref="T:System.Net.Sockets.Socket" /> used to send and receive data.
/// </returns>
/// <exception cref="T:System.InvalidOperationException">The listener has not been started with a call to <see cref="M:System.Net.Sockets.TcpListener.Start" />.</exception>
/// <PermissionSet><IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" /><IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /></PermissionSet>
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;
}
}