【问题标题】:HttpClient with .Net Core 2.1 hangs.Net Core 2.1 的 HttpClient 挂起
【发布时间】:2018-11-17 19:55:22
【问题描述】:

鉴于以下 .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 Core 2.0 并且它工作正常...

注意

我尝试过使用:

HttpClientFactory -> Same result
WebRequest        -> Same result

想法?

更新 1 这在不在公司网络上时有效,这可能意味着代理行为的改变。但是,core2.0 仍然可以正常工作,因此试图找出差异。

更新 2 貌似引入了一个bug,被举报了……

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

【问题讨论】:

  • 一种选择是使用新的 HttpClientFactory,它是 HttpClient 上的升级/补丁(重新制作并解决了 httpClient 的问题)。看看这个stevejgordon.co.uk/introduction-to-httpclientfactory-aspnetcore
  • 我也尝试过使用 HttpClientFactory,结果相同。还尝试了旧的 WebRequest,结果相同
  • 我试过异步,没有帮助。为了简单起见,我把它省略了。
  • 刚刚尝试了“jsonplaceholder.typicode.com/posts/1”。也无法连接..重试,第三次成功。
  • 嘿@Jim 我不知道它是否有帮助,但 Scott H. 提到了一些关于 2.1 中偶尔发生的 HttpRequestException .. 你可能想看看它.. 不知道它是否真的对你有帮助..hanselman.com/blog/…

标签: c# .net .net-core asp.net-core-2.1 .net-core-2.1


【解决方案1】:

CoreFx 2.1 中的更改导致HttpClient 使用新的HttpClientHandler。这可能是您的问题的原因以及降级工作的原因。

有很多方法可以重置处理程序,您可以在change log 中了解更多信息。您可以通过使用 WinHttpHandler 作为参数实例化 HttpClient、将环境变量 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER 设置为 false 或在代码中调用以下代码来使用旧的 HttpHandler:

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

【讨论】:

  • 我的代码在家里运行良好。它似乎只在公司网络上。但是,我尝试了您的建议,但仍然无法在 corp 网络上运行。
  • 在最新的 net core 2.1 中还需要这个吗?我的代码中仍然暂时有这个,所以一切正常。
  • 我尝试在我们的 net core 2.2 应用程序中删除这一行,但仍然存在与 net core 2.1 相同的问题。谁能确认一下?
  • 我仍然在 dotnet core 3.1 上看到这个。关闭 UseSocketsHttpHandler 将我在 macos 上的性能从几分钟提高到几秒钟
【解决方案2】:

因此,显然报告了一个错误/重大更改。

这里: 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找到的

【讨论】:

  • 不幸的是,这仅适用于我在使用 System.Net.Http.WinHttpHandler 4.6.0-preview1 时的问题。该软件包由每日构建 nuget 商店dotnet.myget.org/F/dotnet-core/api/v3/index.json 提供。
  • @ToniWenzel 我在哪里可以得到这个版本?我在 NuGet 上找到的最接近的是 4.6.0-preview.18571.3,但它不起作用
  • @Lovy我目前使用的是 4.6.0-preview1-26627-01。 dotnet.myget.org/feed/dotnet-core/package/nuget/…
  • 好吧,我只是忘了添加 nuget 每日构建包源。仍然不能解决我的问题
【解决方案3】:

这是一个著名的“21 秒”超时问题... 在 Azure 中对很少调用的服务有什么帮助(我的服务是从 Azure 基础架构调用外部服务)正在添加:

httpClient.DefaultRequestHeaders.ConnectionClose = true;

【讨论】:

  • 更多关于这个“著名的 21 秒超时问题”的链接,请?我想我也有。 HttpRequestException 和 SocketException 通过 HttpClient 从 Azure 函数(在 apim 后面)到下游/源系统
  • 你可以google 21秒延迟超时,例如getin2me.blogspot.com/2010/08/…
猜你喜欢
  • 1970-01-01
  • 2020-03-22
  • 1970-01-01
  • 1970-01-01
  • 2018-12-25
  • 2019-08-03
  • 2023-03-14
  • 1970-01-01
  • 2013-11-03
相关资源
最近更新 更多