代码之家  ›  专栏  ›  技术社区  ›  Jim

带有.NET Core 2.1的HttpClient挂起

  •  8
  • Jim  · 技术社区  · 8 年前

    给定以下.NET Core 2.1控制台应用程序…

    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());
                }
            }
        }
    }
    

    对GetAsync的调用挂起,引发异常,并显示以下消息:

    system.net.http.httprequestexception:连接尝试失败 因为关联方在 时间,或建立的连接失败,因为连接的主机 未能响应--->system.net.sockets.socketexception:a 连接尝试失败,因为连接方不正确 一段时间后响应,或建立的连接失败 因为连接的主机无法响应

    但是,切换到.NET Core2.0,它可以正常工作…

    注释

    我试过使用:

    HttpClientFactory -> Same result
    WebRequest        -> Same result
    

    思想?

    更新1 当不在公司网络上时,这可能意味着代理行为的改变。然而,core2.0仍然可以工作,所以我们试图找出区别。

    更新2 好像是引入了一个错误,然后报告…

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

    3 回复  |  直到 8 年前
        1
  •  12
  •   Daniel Gimenez    8 年前

    corefx 2.1中的一个更改导致 HttpClient 使用新的 HttpClientHandler . 这可能是你的问题的原因以及降级的原因。

    有很多方法可以重置处理程序,您可以在 change log . 您可以使用旧的httphandler,方法是用winhttphandler作为参数实例化httpclient,并设置环境变量 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER 设置为false,或在代码中调用以下命令:

    AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
    
        2
  •  9
  •   Jim    8 年前

    所以很明显这上面有个错误/破坏性的变化。

    在这里: https://github.com/dotnet/corefx/issues/30166 https://github.com/dotnet/corefx/issues/30191

    两个独立但相关的问题,我相信是我所经历的。

    不过,我找到了一个解决办法。

    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;
                }
            }
        }
    }
    

    这里的关键是 WinHttpHandler 并设置 WindowsProxyUsePolicy 到 WindowsProxyUsePolicy.UseWinInetProxy

    WinHttpHandler程序 通过添加nuget包找到 System.Net.Http.WinHttpHandler

        3
  •  0
  •   Pavel Biryukov    7 年前

    这是一个著名的“21秒”超时问题… 在azure中,使用罕见调用(我的服务正在从azure基础架构调用外部服务)的服务有助于添加:

    httpClient.DefaultRequestHeaders.ConnectionClose = true;
    
    推荐文章