web-dev-qa-db-fra.com

HttpClient avec .Net Core 2.1 se bloque

Étant donné l'application de console .Net Core 2.1 suivante ...

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;

namespace TestHttpClient
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (var httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));                    

                    string url = "https://jsonplaceholder.typicode.com/posts/1";
                    var response = httpClient.GetAsync(url).Result;
                    string jsonResult = response.Content.ReadAsStringAsync().Result;   
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
        }
    }
}

L'appel à GetAsync se bloque en lançant une exception avec le message suivant:

System.Net.Http.HttpRequestException: une tentative de connexion a échoué car la partie connectée n'a pas répondu correctement après un certain temps ou la connexion établie a échoué car l'hôte connecté n'a pas répondu ---> System.Net.Sockets.SocketException: A la tentative de connexion a échoué car la partie connectée n'a pas répondu correctement après un certain temps ou la connexion établie a échoué car l'hôte connecté n'a pas répondu

Cependant, passez à .Net Core 2.0 et cela fonctionne très bien ...

[~ # ~] note [~ # ~]

J'ai essayé d'utiliser:

HttpClientFactory -> Same result
WebRequest        -> Same result

Pensées?

MISE À JOUR 1 Cela fonctionne lorsque vous n'êtes pas sur le réseau d'entreprise, ce qui pourrait signifier un changement de comportement avec le proxy. Cependant, core2.0 fonctionne toujours, alors essayez de trouver la différence.

MISE À JOUR 2 On dirait qu'un bug a été introduit et il est rapporté ...

https://github.com/dotnet/corefx/issues/30166#issuecomment-3954896

10
Jim

Donc apparemment, il y a un changement de bug/rupture signalé à ce sujet.

Ici: https://github.com/dotnet/corefx/issues/30166https://github.com/dotnet/corefx/issues/30191

Je crois que ce que je vis est deux problèmes distincts mais liés.

Cependant, j'ai trouvé ce qui semble être une solution de contournement.

using System;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace TestHttpClient
{
    static class Program
    {
        static async Task Main(string[] args)
        {
            try
            {
                using (var httpClient = new HttpClient(new WinHttpHandler() { WindowsProxyUsePolicy = WindowsProxyUsePolicy.UseWinInetProxy }))
                {
                    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                    string url = "https://jsonplaceholder.typicode.com/posts/1";                   

                    var response = await httpClient.GetAsync(url);
                    string jsonResult = await response.Content.ReadAsStringAsync();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                throw;
            }
        }
    }
}

L'essentiel ici est d'utiliser WinHttpHandler et de définir WindowsProxyUsePolicy sur WindowsProxyUsePolicy.UseWinInetProxy

WinHttpHandler est trouvé en ajoutant un paquet nuget System.Net.Http.WinHttpHandler

9
Jim

Il s'agissait d'un changement dans CoreFx 2.1 qui oblige le HttpClient à utiliser un nouveau HttpClientHandler. C'est peut-être la cause de votre problème et pourquoi le déclassement fonctionne.

Il existe de nombreuses façons de réinitialiser le gestionnaire et vous pouvez en savoir plus à ce sujet dans le change log . Vous pouvez utiliser l'ancien HttpHandler en instanciant un HttpClient avec un WinHttpHandler comme paramètre, en définissant la variable d'environnement DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER à false, ou en appelant ce qui suit dans votre code:

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
12
Daniel Gimenez

Il s'agit d'un célèbre problème de délai d'attente de "21 secondes" ... Ce qui aide dans Azure pour le service avec des appels rares (mon service appelle un service externe à partir de l'infrastructure Azure) ajoute:

httpClient.DefaultRequestHeaders.ConnectionClose = true;
0
Pavel Biryukov