HttpClient和套接字用尽-澄清吗? - c#

This article表示我们应该使用静态的HttpClient以便重用套接字。

但是那里的第一条评论说存在DNS更改识别问题,解决方案在另一篇文章here中:

第二篇文章建议:

var client = new HttpClient();
client.DefaultRequestHeaders.ConnectionClose = true; 

哪个控制KeepAlive标头。
但是会阻止您利用重新使用套接字的好处

另一个解决方案是:

var sp = ServicePointManager.FindServicePoint(new Uri("http://foo.bar/baz/123?a=ab"));
sp.ConnectionLeaseTimeout = 60*1000; // 1 minute

但:

他没有说我们每次发出请求时应该使用new Httpclient,还是应该使用静态请求。

题:

说我想使用这个解决方案:

var sp = ServicePointManager.FindServicePoint(new Uri("http://foo.bar/baz/123?a=ab"));
sp.ConnectionLeaseTimeout = 60*1000; // 1 minute 

我应该仍然使用static HttpClient方法吗?还是每次我要拨打电话时都要new HttpClient
或者-我应该为每个new HttpClient创建静态/非静态scheme://basedns吗?

他展示了问题,但是他的结论没有给出完整的最终解决方案。

请注意-我在问.net框架。不是.net Core。

参考方案

那是一篇非常古老的文章,确实说明了为什么应重用HttpClient,但没有说明如何处理DNS更改。 Singleton HttpClient? Beware of this serious behaviour and how to fix it中对此进行了解释。那仍然只处理一个连接。

显而易见的答案是避免单例HttpClient,但仍会重用它们一段时间。此外,不同的套接字用于连接到不同的服务器,这意味着我们确实需要在每个服务器上重用(和回收)套接字。
该解决方案后来以HttpClientFactory的形式出现。

令人高兴的是HttpClientFactory是一个.NET Standard 2.0包,Microsoft.Extensions.Http可以由.NET Core和.NET Old使用,而不仅仅是ASP.NET Core应用程序。例如,我在控制台应用程序中使用它。

史蒂夫·戈登(Steve Gordon)的HttpClientFactory in ASP.NET Core 2.1 (PART 1)以及他在该series中的所有文章都是非常好的介绍。

简而言之,每次我们想要HttpClient时,我们都向工厂索要一个实例:

[Route("api/[controller]")]
public class ValuesController : Controller
{
    private readonly IHttpClientFactory _httpClientFactory;

    public ValuesController(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    [HttpGet]
    public async Task<ActionResult> Get()
    {
        var client = _httpClientFactory.CreateClient();
        var result = await client.GetStringAsync("http://www.google.com");
        return Ok(result);
    }
}

HttpClient将工作委托给SocketClientHandler。那就是需要重用的东西。 HttpClientFactory产生HttpClient实例,该实例重新使用套接字处理程序池中的套接字处理程序。处理程序会定期回收以处理DNS更改。

更好的是,HttpClientFactory can be combined with Polly将重试逻辑添加到HttpClient实例。它通过配置处理程序在后台执行此操作。

java.net.URI.create异常 - java

java.net.URI.create("http://adserver.adtech.de/adlink|3.0") 抛出java.net.URISyntaxException: Illegal character in path at index 32: http://adserver.adtech.de/adlink|3.0 虽然n…

当回复有时是一个对象有时是一个数组时,如何在使用改造时解析JSON回复? - java

我正在使用Retrofit来获取JSON答复。这是我实施的一部分-@GET("/api/report/list") Observable<Bills> listBill(@Query("employee_id") String employeeID); 而条例草案类是-public static class…

在ASP.NET WebForms中在服务器端初始化bootsrap datatimepicker - javascript

我有这个HTML<div class='datepicker input-group date' id='datetimepickerStart'> <input type='text' class="form-control" /> <span c…

ImageButton中的无效回发或回调参数 - c#

我的Click事件删除按钮(图像按钮)时遇到问题。我知道对此还有其他疑问,但是我什么都不懂!我不明白没有答案!我做了所有其他所有问题中指定的内容!此页面中使“重定向”到示例的其他事件效果很好!我很清楚?需要更多细节吗?堆栈跟踪或更多代码?错误是: 无效的回发或回调参数。使用配置或页面中的启用事件验证。为了安全起见,此功能验证回发或回调事件的参数源自最初呈现它…

Mongo汇总 - javascript

我的收藏中有以下文件{ "_id": ObjectId("54490b8104f7142f22ecc97f"), "title": "Sample1", "slug": "samplenews", "cat": …