es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cancelar la tarea de escucha al cerrar su socket asociado.

Tengo un TcpListener, que se puede iniciar

public void Start()
{
    if (!Listening && !IsDisposed)
    {
        <em>socket.Bind(</em>localEndpoint);
        Task.Run(DoListen);
    }
}

<p>private async Task DoListen()
{
    _socket.Listen();
    Listening = true;
    try
    {
        while (Listening)
        {
            var socket = await _socket.AcceptAsync().ConfigureAwait(false);
            NewConnection?.Invoke(new Connection(socket));
        }
    }
    catch (SocketException e)
    {
        Stop();
    }
    finally
    {
        Listening = false;
    }
}

y se detiene

public void Stop()
{
    _socket?.Close();
    IsDisposed = true;
    Listening = false;
}

¿Cómo puedo cancelar la tarea iniciada llamando a Start()?
Al hacer la condición de los bucles Listening, puedo asegurarme de que la tarea se detendrá cuando se evalúe la condición.
Sin embargo, esto solo ocurriría después de que se acepte una nueva conexión.
¿Cómo puedo salir de la espera de var socket = await _socket.AcceptAsync().ConfigureAwait(false);?
¿Qué sucede si el socket asociado se cierra mientras se espera AcceptAsync()?
¡Gracias por sus respuestas!

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para cancelar la tarea iniciada llamando a Start(), puedes usar un CancellationToken. Primero, agrega un parámetro CancellationToken a la firma del método DoListen():

    private async Task DoListen(CancellationToken cancellationToken)
    

    Luego, pasa un CancellationToken al método DoListen() cuando se llama en Start(). Puedes crear un CancellationTokenSource y usar su propiedad Token para pasar el CancellationToken:

    private CancellationTokenSource _cancellationTokenSource;
    
    public void Start()
    {
        if (!Listening && !IsDisposed)
        {
            _socket.Bind(_localEndpoint);
            _cancellationTokenSource = new CancellationTokenSource();
            Task.Run(() => DoListen(_cancellationTokenSource.Token));
        }
    }
    

    Para salir de la espera de AcceptAsync(), puedes llamar al método Cancel() del CancellationTokenSource. Esto provocará que se lance una OperationCanceledException dentro de DoListen(), que puedes capturar y manejar.

    Si se cierra el socket asociado mientras se espera AcceptAsync(), se lanzará una SocketException, que ya estás capturando en tu código. Podrías agregar algún manejo adicional o registro a este bloque de captura si lo deseas.

Comments are closed.