tengo este código ...Detención de una TcpListener después de llamar BeginAcceptTcpClient
internal static void Start()
{
TcpListener listenerSocket = new TcpListener(IPAddress.Any, 32599);
listenerSocket.Start();
listenerSocket.BeginAcceptTcpClient(new AsyncCallback(AcceptClient), null);
}
Entonces mi llamada de vuelta función se parece a esto ...
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);
}
Ahora, llamo BeginAcceptTcpClient, después de algún tiempo más tarde quiero detener el servidor. Para hacer esto, he estado llamando a TcpListener.Stop() o TcpListener.Server.Close(). Sin embargo, ambos ejecutan mi función AcceptClient. Esto arroja una excepción cuando llamo a EndAcceptTcpClient. ¿Cuál es la mejor forma de evitar esto? Podría poner una bandera para detener la ejecución de AcceptClient una vez que haya llamado "stop", pero me pregunto si me está perdiendo algo.
Actualización 1
Actualmente he parcheado cambiando el código para tener este aspecto.
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();
}
Actualización 2
lo cambié a impliment la respuesta de 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);
}
}
No es necesario poner en cola otro hilo para realizar el trabajo de manipulación; simplemente puede llamar al EndAcceptTcpClient para decirle al oyente que se maneja, y luego llamar a BeginAcceptTcpClient justo después para programar otro manejo. Use el hilo actual para manejar la solicitud que acaba de recibir. –