带有 .Net Core 2.1 的 HttpClient 挂起
HttpClient with .Net Core 2.1 hangs
鉴于以下 .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: A connection attempt failed
because the connected party did not properly respond after a period of
time, or established connection failed because connected host has
failed to respond ---> System.Net.Sockets.SocketException: A
connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed
because connected host has failed to respond
但是,切换到 .Net Core 2.0,它工作正常...
注意
我试过使用:
HttpClientFactory -> Same result
WebRequest -> Same result
想法?
更新 1
这在不在公司网络上时有效,这可能意味着代理的行为发生变化。然而,core2.0仍然可以正常工作,因此试图找出差异。
更新 2
似乎引入了错误并报告...
https://github.com/dotnet/corefx/issues/30166#issuecomment-395489603
CoreFx 2.1 中的一项更改导致 HttpClient
使用新的 HttpClientHandler
。这可能是您遇到问题的原因,也是降级有效的原因。
有很多方法可以重置处理程序,您可以在 change log 中阅读更多相关信息。您可以使用旧的 HttpHandler,方法是使用 WinHttpHandler 作为参数实例化 HttpClient,将环境变量 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER
设置为 false,或者在您的代码中调用以下代码:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
显然有一个 bug/breaking 的变化报告。
这里:
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
这是一个著名的“21 秒”超时问题...
在 Azure 中对罕见调用的服务有帮助(我的服务是从 Azure 基础设施调用外部服务)正在添加:
httpClient.DefaultRequestHeaders.ConnectionClose = true;
鉴于以下 .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: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
但是,切换到 .Net Core 2.0,它工作正常...
注意
我试过使用:
HttpClientFactory -> Same result
WebRequest -> Same result
想法?
更新 1 这在不在公司网络上时有效,这可能意味着代理的行为发生变化。然而,core2.0仍然可以正常工作,因此试图找出差异。
更新 2 似乎引入了错误并报告...
https://github.com/dotnet/corefx/issues/30166#issuecomment-395489603
CoreFx 2.1 中的一项更改导致 HttpClient
使用新的 HttpClientHandler
。这可能是您遇到问题的原因,也是降级有效的原因。
有很多方法可以重置处理程序,您可以在 change log 中阅读更多相关信息。您可以使用旧的 HttpHandler,方法是使用 WinHttpHandler 作为参数实例化 HttpClient,将环境变量 DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER
设置为 false,或者在您的代码中调用以下代码:
AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);
显然有一个 bug/breaking 的变化报告。
这里: 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
这是一个著名的“21 秒”超时问题... 在 Azure 中对罕见调用的服务有帮助(我的服务是从 Azure 基础设施调用外部服务)正在添加:
httpClient.DefaultRequestHeaders.ConnectionClose = true;