为每个webrequest或单个实例创建httpclient实例。 [英] Create httpclient instance per webrequest or single instance.

查看:156
本文介绍了为每个webrequest或单个实例创建httpclient实例。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,



我读过很多关于HttpClient的文章。在一些文章中,提到了创建httpclient的单个实例并在整个应用程序中重用它。但是在一些文章中提到了每个webrequest创建一个新的httpclient实例。



Hi All,

I have read so many articles on HttpClient. In some articles, it is mentioned to create single instance of httpclient and reuse it in the entire application. But in some articles it is mentioned to create new instance of httpclient per webrequest.

**// New instance per web request. It disposes the httpClient after use.**
using(var httpClient = new HttpClient())
{
   //  Get/ Post/ Put/ Delete
}



您能否告诉我哪种方法更好?



我创建了一个小POC。测试1:httpclient的单个实例。




Could you please let me know which approach is the better?

I have created a small POC. Test 1 : Single instance of httpclient.

private static readonly HttpClient _httpClient = new HttpClient();
// Note : Application Hosted in Local IIS
private const string ServerGetUrl = "http://localhost:80/api/service/getdata";
private static void TestPingWithSingleInstance()
    {

        Parallel.For(0, 5,
            i =>
            {
                    _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    var response = _httpClient.GetAsync(ServerGetUrl).GetAwaiter().GetResult();
                    var data = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    Console.WriteLine(data);
                    Console.WriteLine("==============="); 
            });
}



当我解雇netstat命令时。它显示5个开放端口。



TCP 127.0.0.1:46336 DESKTOP-OEOGI0L:http ESTABLISHED

TCP 127.0.0.1:46337 DESKTOP- OEOGI0L:http ESTABLISHED

TCP 127.0.0.1:46338 DESKTOP-OEOGI0L:http ESTABLISHED

TCP 127.0.0.1:46339 DESKTOP-OEOGI0L:http ESTABLISHED

TCP 127.0.0.1:46340 DESKTOP-OEOGI0L:http ESTABLISHED

测试2:按webrequest创建实例。




When I fired netstat command. It displays 5 open ports.

TCP 127.0.0.1:46336 DESKTOP-OEOGI0L:http ESTABLISHED
TCP 127.0.0.1:46337 DESKTOP-OEOGI0L:http ESTABLISHED
TCP 127.0.0.1:46338 DESKTOP-OEOGI0L:http ESTABLISHED
TCP 127.0.0.1:46339 DESKTOP-OEOGI0L:http ESTABLISHED
TCP 127.0.0.1:46340 DESKTOP-OEOGI0L:http ESTABLISHED
Test 2 : Create instance per webrequest.

private static void TestPingWithDisposableInstance()
{
using (var httpClient = new HttpClient())
                {
                    httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                    var response = httpClient.GetAsync(ServerGetUrl).GetAwaiter().GetResult();
                    var data = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    Console.WriteLine(data);
                    Console.WriteLine("===============");
                }

}



当我解雇netstat命令时。它显示5个开放端口。



TCP 127.0.0.1:46233 DESKTOP-OEOGI0L:http TIME_WAIT

TCP 127.0.0.1:46234 DESKTOP- OEOGI0L:http TIME_WAIT

TCP 127.0.0.1:46235 DESKTOP-OEOGI0L:http TIME_WAIT

TCP 127.0.0.1:46236 DESKTOP-OEOGI0L:http TIME_WAIT

TCP 127.0.0.1:46237 DESKTOP-OEOGI0L:http TIME_WAIT





如果我们使用单个实例,将打开相同数量的端口或每个webrequest的实例。你能告诉我更好的方法吗?



注意:我使用的是.Net 4.5.1框架。



提前致谢。



我的尝试:



我创建了一个上面的POC。为这两种方法打开相同数量的端口。


When I fired netstat command. It displays 5 open ports.

TCP 127.0.0.1:46233 DESKTOP-OEOGI0L:http TIME_WAIT
TCP 127.0.0.1:46234 DESKTOP-OEOGI0L:http TIME_WAIT
TCP 127.0.0.1:46235 DESKTOP-OEOGI0L:http TIME_WAIT
TCP 127.0.0.1:46236 DESKTOP-OEOGI0L:http TIME_WAIT
TCP 127.0.0.1:46237 DESKTOP-OEOGI0L:http TIME_WAIT


Same numbers of ports will be open if we use single instance or instance per webrequest. Could you please let me know the better approach ?

Note : I am using .Net 4.5.1 framework.

Thanks in advance.

What I have tried:

I have created a above POC. Same number of ports open for both the approaches.

推荐答案

两种方式都可以。 HttpClient可以重复使用。



我建议使用单个HttpClient实例。拥有一个实例,您可以从 DefaultRequestHeaders属性 [ ^ ]和 BaseAddress属性 [ ^ ]。更重要的是,仅使用单个HttpClient实例将提高应用程序的性能和稳定性。这篇博文详细描述了:您使用的HttpClient错误,它会破坏您的软件稳定性ASP.NET Monsters [ ^ ]
Both ways will work. A HttpClient can be reused.

I recommend using a single HttpClient instance. With having a single instance, you can benefit from the DefaultRequestHeaders property[^] and BaseAddress property[^]. Even more importantly, just using a single HttpClient instance will improve performance and stability of your application. This blog post describes that in detail: You're using HttpClient wrong and it is destabilizing your software | ASP.NET Monsters[^]


经过大量的研究和讨论。我发现最好的方法是在整个应用程序中使用相同的HttpClient实例。



使用这种方法时需要记住的一些关键内容。

a)在应用程序启动时创建HttpClient实例并将其注入整个应用程序。

b)只设置一次默认标头。主要是在申请开始时。



但在用户特定情况下。我们需要根据用户设置标头。那么问题是如何处理这种情况?

解决方案:



After lot of research and discussion. I found the best approach is to use same instance of HttpClient through out the application.

Some key stuffs you need to remember while using this approach.
a) Create HttpClient instance at application start and inject it through out the application.
b) Set default headers only once. Mostly at application start.

But in User specific scenarios. We need to set the headers according to users. So the question arises how to handle this kind of scenarios ?
Solution :

Parallel.For(0, 10,
                i =>
                {
                    var guidData = Guid.NewGuid().ToString();
                    _httpClient.DefaultRequestHeaders.Clear();
                    _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));                        
var response = _httpClient.CustomGetAsync("http://localhost:2967/api/service/GetData", x => x.Headers.Add("Guid", guidData)).GetAwaiter().GetResult();
                    var data = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    Console.WriteLine(data);
                    Console.WriteLine("===============");
                });<pre lang="c#">







创建操纵标题的扩展方法:




Create extension method to manipulate header :

public static Task<HttpResponseMessage> CustomGetAsync(this HttpClient httpClient, string url, Action<HttpRequestMessage> manipulateData)
        {
            var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, url);

            manipulateData(httpRequestMessage);

            return httpClient.SendAsync(httpRequestMessage);
        }


这篇关于为每个webrequest或单个实例创建httpclient实例。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆