Tempo limite em solicitações HTTP do Xamarin

Boa noite!

Eu estava tentando limpar / refinar algum código e acabei encontrando problemas comtempos limite em solicitações HTTP do Xamarin (conforme descrito no meu tópico original:Download assíncrono e desserializar)

Problema encontrado (testado apenas com o Xamarin.Android; não sei sobre o iOS):

Quando umhost não pode ser alcançado (por exemplo, um servidor local offline),GetAsync lança umSystem.Net.WebException depois de aproximadamente3 minutos com a mensagemErro: ConnectFailure (conexão expirou). A exceção interna éSystem.Net.Sockets.SocketsException (log completo aqui:http://pastebin.com/MzHyp2FM)

Código:

internal static class WebUtilities
{
    /// <summary>
    /// Downloads the page of the given url
    /// </summary>
    /// <param name="url">url to download the page from</param>
    /// <param name="cancellationToken">token to cancel the download</param>
    /// <returns>the page content or null when impossible</returns>
    internal static async Task<string> DownloadStringAsync(string url, CancellationToken cancellationToken)
    {
        try
        {
            // create Http Client and dispose of it even if exceptions are thrown (same as using finally statement)
            using (var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) })
            {
                // should I always do this?
                client.CancelPendingRequests();

                // Issue here; Timeout of roughly 3 minutes
                using (var response = await client.GetAsync(url, cancellationToken).ConfigureAwait(false))
                {
                    // if response was successful (otherwise return null)
                    if (response.IsSuccessStatusCode)
                    {
                        // return its content
                        return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    }
                }
            }
        }
        // TODO: split exceptions?
        catch (Exception ex) when (ex is System.Net.Sockets.SocketException ||
                                    ex is InvalidOperationException ||
                                    ex is OperationCanceledException ||
                                    ex is System.Net.Http.HttpRequestException)
        {
            WriteLine("DownloadStringAsync task has been cancelled.");
            WriteLine(ex.Message);
            return null;
        }

        // return null if response was unsuccessful
        return null;
    }
}

Método de chamada:

internal static async Task CallAsync(string url)
    {
        using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)))
        {
            var token = cts.Token;
            token.ThrowIfCancellationRequested();

            string result = await WebUtilities.DownloadStringAsync(url, token).ConfigureAwait(false);
        }
    }

Configuraçãoclient.Timeout parece não funcionar.

De qualquer jeito,cancelamento automático de voz após 10 segundos?

Esse problema de tempo limite ocorre quando:

É solicitado um endereço IP offline / inacessível (no meu caso, um servidor local offline como 192.168.1.101:8080) (ou seja, usandoGetAsync, SendAsync, GetResponseAsync)

O código funciona bem quando:

A solicitação é feita a partir de umcliente de desktop (por exemplo.,WPF) Se o IP estiver offline / inacessível, lançará 4 exceções muito rapidamente (Nenhuma conexão pôde ser estabelecida porque a máquina de destino a recusou ativamente)

Conclusões

Xamarin parece ter algumbugs em solicitações HTTP (com tempos limite pelo menos?), pois eles não fornecem os resultados esperados. E pelo que li, pode ser algo que existe há alguns anos (desde 2012 ou 2013).

O teste de unidade Xamarin também não ajuda:https://github.com/xamarin/xamarin-android/blob/1b3a76c6874853049e89bbc113b22bc632ed5ca4/src/Mono.Android/Test/Xamarin.Android.Net/HttpClientIntegrationTests.cs

Editar

Timeout = TimeSpan.FromMilliseconds(1000) - trabalhoTimeout = Timeout = TimeSpan.FromSeconds(1) - não funciona (?????)Timeout = TimeSpan.FromMilliseconds(2000) (e acima) - não funciona

Alguma ideia? Obrigado!

questionAnswers(1)

yourAnswerToTheQuestion