Thread.Abort scheint nicht eine Threadabort zu werfen wegen AcceptSocket
-
01-10-2019 - |
Frage
I ChannelServer.ListeningThread.Abort
auf folgenden Thread nennt, scheint jedoch nichts zu passieren. Ich möchte genauer sein, aber ich kann mir nicht mehr von irgendetwas. Es scheint kein ThreadAbortException
zu sein, die ausgelöst wird, und diese Ausnahme sollte unabhängig von den Sperr Zuhörern geworfen werden (es funktioniert perfekt auf Threads, die blockierend-Empfang ist).
Wichtige EDIT : Mit einem ManualResetEvent.WaitOne
statt AcceptSocket
, wie Lyrik zur Prüfung vorgeschlagen hat, es funktioniert perfekt. Wie kommt es AcceptSocket
blockiert die ThreadAbortException
?
LINK : Dieses Forum Thread scheint das gleiche Problem zu diskutieren, obwohl ich verstehe nicht alles aus ihm heraus: 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();
Lösung 2
Dies funktioniert, aber es ist unglaublich nachlässig und fade Auszehrung. Könnte jemand auf eine Art und Weise zeigen Sie mir nur eine Ausnahme zu werfen, dass „AcceptSocket“ wird nicht automatisch fangen?
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();
Andere Tipps
Ich bin mir nicht sicher, warum Sie diesen Fehler bekommen, aber hier ist ein einfaches Beispiel, das funktioniert:
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();
So ist es für mich funktioniert ... Ich nahm Sie durch den Debugger und Ihre Bruchstelle innerhalb der catch-Anweisung getreten habe nicht getroffen wurde, ist das richtig?
. Hinweis: es ist eine schlechte Praxis zu Call Abort
, stattdessen sollten Sie rufen Interrupt
und behandeln die ThreadInterruptedException
... es ist viel sicherer
Hier ist eine einfache AcceptSocket2
Erweiterungsmethode (sorry für den Mangel an Phantasie in Bezug auf die Namen ...).
Es funktioniert genau wie das Original AcceptSocket
Methode.
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;
}
}