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();
War es hilfreich?

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;
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top