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();
Était-ce utile?

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;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top