Domanda

Chiedo ChannelServer.ListeningThread.Abort su questo thread, ma nulla sembra accadere. Vorrei essere più precisi, ma non riesco a pensare a qualcosa di più. Non sembra esserci alcuna ThreadAbortException che viene gettato, e questa eccezione dovrebbe essere gettato a prescindere di chi ascolta di blocco (che funziona perfettamente su discussioni che sono blockingly ricevitori).

Modifica Importante : Con un ManualResetEvent.WaitOne invece di AcceptSocket, come Lyrik ha suggerito per il test, funziona perfettamente. Come mai blocchi AcceptSocket il ThreadAbortException?

: questo thread del forum sembra per discutere lo stesso problema, anche se non posso figura nulla fuori di esso: 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();
È stato utile?

Soluzione 2

Questo funziona, ma è incredibilmente sciatta e filo-spreco. Qualcuno potrebbe solo punto me un modo per generare un'eccezione che "AcceptSocket" non prenderà automaticamente?

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

Altri suggerimenti

Non so perché che stai ricevendo questo errore, ma qui è un semplice esempio che le opere:

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

Così funziona per me ... ho assunto hai fatto un passo attraverso il debugger e il vostro punto di rottura all'interno della istruzione catch non è stato colpito, è corretto?

. Nota: è cattiva pratica di chiamata Abort, invece si dovrebbe chiamare Interrupt e gestire il ThreadInterruptedException ... è molto più sicuro

Ecco un semplice metodo di estensione AcceptSocket2 (scusate per la mancanza di fantasia per quanto riguarda il nome ...). Funziona esattamente come il metodo 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;
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top