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.

¿Cómo puedo introducir un controlador de tiempo de espera para este subproceso Connect Async en C#?

Quiero escribir un código que se conecte a un servidor, pero que se agote después de 10 segundos. Pensé que Task.WhenAny() haría el truco. Hasta ahora, he llegado con el siguiente código:

private async Task<bool> tryConnect() // Se agota después de 10 segundos
{
    bool connected = false;
    bool alreadyWentOut = false;
    await Task.WhenAny(
        Task.Run(async() =>
        {
            try
            {
                return connected = await CrossInAppBilling.Current.ConnectAsync();
            }
            finally
            {
                if (alreadyWentOut) await CrossInAppBilling.Current.DisconnectAsync();
            }
        }),
        Task.Delay(10000)
    );
    alreadyWentOut = true;
    return connected;
}

¿Hay un olor en el código actual? En mi IDE (usando JetBrains Rider) me está dando la siguiente advertencia:

enter image description here

Si hay un olor en el código, ¿cómo implementarlo de manera mejor?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La advertencia en el IDE sugiere que la llamada Task.Run no es necesaria ya que CrossInAppBilling.Current.ConnectAsync() ya es un método asíncrono.

    Una mejor implementación sería simplemente esperar la llamada ConnectAsync utilizando también el método Task.Delay para establecer un tiempo de espera:

    private async Task<bool> tryConnect()
    {
        bool connected = false;
        var connectTask = CrossInAppBilling.Current.ConnectAsync();
        var timeoutTask = Task.Delay(10000);
    
        var completedTask = await Task.WhenAny(connectTask, timeoutTask);
    
        if (completedTask == connectTask)
        {
            connected = true;
        }
        else
        {
            await CrossInAppBilling.Current.DisconnectAsync();
        }
    
        return connected;
    }
    

    Esta implementación crea dos tareas: una para la llamada ConnectAsync y otra para el tiempo de espera. Utilizando Task.WhenAny, el código espera a que cualquiera de las tareas se complete y luego verifica cuál tarea se completó. Si la llamada ConnectAsync se completó antes del tiempo de espera, el código devuelve true. Si el tiempo de espera se completó antes de la llamada ConnectAsync, el código se desconecta del servidor y devuelve false.

Comments are closed.