首页 文章

带有.Net Core 2.1的HttpClient挂起

提问于
浏览
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:连接尝试失败,因为连接方在一段时间后没有正确响应,或者由于连接主机无法响应而 Build 连接失败---> System.Net.Sockets.SocketException:连接尝试失败,因为连接方在一段时间后没有正确响应,或者 Build 的连接失败,因为连接的主机无法响应

However, switch to .Net Core 2.0 and it works fine...

NOTE

我尝试过使用:

HttpClientFactory -> Same result
WebRequest        -> Same result

思考?

UPDATE 1 这不适用于企业网络,这可能意味着代理行为可能会发生变化 . 然而,core2.0仍然可以工作,所以试图找到差异 .

UPDATE 2 看起来像是一个bug被引入并报告了......

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

3 回答

  • 0

    这是一个着名的“21秒”超时问题...在Azure中提供罕见呼叫服务(我的服务是从Azure基础架构调用外部服务)有助于添加:

    httpClient.DefaultRequestHeaders.ConnectionClose = true;
    
  • 7

    显然,有一个错误/突破性的变化报告 .

    这里: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

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

  • 8

    这是CoreFx 2.1的一个变化,导致 HttpClient 使用新的 HttpClientHandler . 这可能是您的问题的原因以及降级的原因 .

    有许多方法可以重置处理程序,您可以在change log中阅读有关它的更多信息 . 您可以通过使用WinHttpHandler作为参数实例化HttpClient,将环境变量 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER 设置为false,或者在代码中调用以下内容来使用旧的HttpHandler:

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

相关问题