Ho questo codice ...Arresto di un TcpListener dopo aver chiamato BeginAcceptTcpClient
internal static void Start()
{
TcpListener listenerSocket = new TcpListener(IPAddress.Any, 32599);
listenerSocket.Start();
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
Poi funzione mia chiamata di nuovo si presenta così ...
private static void AcceptClient(IAsyncResult asyncResult)
{
MessageHandler handler = new MessageHandler(listenerSocket.EndAcceptTcpClient(asyncResult));
ThreadPool.QueueUserWorkItem((object state) => handler.Process());
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
Ora, io chiamo BeginAcceptTcpClient, poi qualche tempo più tardi voglio fermare il server. Per fare questo ho chiamato TcpListener.Stop() o TcpListener.Server.Close(). Entrambi tuttavia eseguono la mia funzione AcceptClient. Ciò quindi genera un'eccezione quando chiamo EndAcceptTcpClient. Qual è il modo migliore per fare questo? Potrei semplicemente mettere un flag per fermare l'esecuzione di AcceptClient una volta che ho chiamato stop, ma mi chiedo se mi manca qualcosa.
Update 1
Attualmente ho rattoppato che modificando il codice a guardare come questo.
private static void AcceptClient(IAsyncResult asyncResult)
{
if (!shutdown)
{
MessageHandler handler = new MessageHandler(listenerSocket.EndAcceptTcpClient(asyncResult));
ThreadPool.QueueUserWorkItem((object state) => handler.Process());
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
}
private static bool shutdown = false;
internal static void Stop()
{
shutdown = true;
listenerSocket.Stop();
}
Update 2
ho cambiato in impliment la risposta da Spencer Ruport.
private static void AcceptClient(IAsyncResult asyncResult)
{
if (listenerSocket.Server.IsBound)
{
MessageHandler handler = new MessageHandler(listenerSocket.EndAcceptTcpClient(asyncResult));
ThreadPool.QueueUserWorkItem((object state) => handler.Process());
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
}
Non è necessario mettere in coda un altro thread per eseguire il lavoro di gestione; puoi semplicemente chiamare EndAcceptTcpClient per dire al listener che è gestito, e poi chiamare un BeginAcceptTcpClient subito dopo per pianificare un'altra gestione. Usa il thread corrente per gestire la richiesta appena ricevuta. –