在.NET Core中正确使用HttpClient的方式

news2025/1/12 20:09:38

HttpClient 是 .NET Framework、.NET Core 或 .NET 5以上版本中的一个类,用于向 Web API 发送 HTTP 请求并接收响应。它提供了一些简单易用的方法,如 GET、POST、PUT 和 DELETE,可以很容易地构造和发送 HTTP 请求,并处理响应数据。它是我们比较常用的官方HTTP请求组件,那么你们都正确使用了吗?本文将探讨HttpClient的正确使用。

环境准备

首先我们用vs2022创建一个带默认 WeatherForcast 模板的 Web API 应用程序,以及一个普通的API的程序,项目使用的是.NET6。

项目结构如下

 

 

两个项目的功能点:

HttpClientTest - 返回天气预报的Web API

HttpClientTest2 -这个项目将用HttpClient来请求HttpClientTest 的天气预备。

接下来我们用4种方法来说明HttpClient的正确使用方法。

方法1

我们首先在HttpClientTest2 创建HttpClientTestController类,并写一个请求天气预备的方法,代码如下:

namespace HttpClientTest2.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class HttpClientTestController : ControllerBase
    {
        [HttpGet]
        public async Task<string> TestHttpClient()
        {
            var url = "https://localhost:7281/WeatherForecast";
            #region 版本1
            var httpClient = new HttpClient();
            var response = await httpClient.GetAsync(url);
            return await response.Content.ReadAsStringAsync();
            #endregion
          }
       }
   }    

 代码写完后,我们设置多项目启动,让这两个项目同时启动。

 

 

项目启动后,执行项目HttpClientTest2 的TestHttpClient请求接口。多执行几次。主要看看HttpClient后台的执行情况。这里可以用netstat来检查http的请求情况。

打开一个CMD控制台程序。输入如下代码:

netstat -na | find "7281"

7281端口是我们请求站点HttpClientTest。多次点击的效果如下:

 

 

由上面可以看出有多个请求,说明请求未关闭。接下来换第二种方法。

方法2

使用using命令来实现请求结束关闭请求,代码如下:

   #region 版本2
    using (var httpClient = new HttpClient())
   {
        var response = await httpClient.GetAsync(url);
        return await response.Content.ReadAsStringAsync();
   }
   #endregion

 同样我们多次请求,结果如下:

 

在这里可以看到状态“TIME_WAIT”,说明链接已经关闭,但实际情况链接还是占用着端口,在资源耗尽才会释放。这就是套连接的问题,套接字耗尽是指服务器上的可用套接字资源已经全部被占用,无法为新的连接提供服务。在 TCP/IP 网络通信中,每个端口上最多只能建立一个连接,这就限制了服务器可以处理的连接数。当服务器负载过高时,就可能导致套接字资源紧张,进而引发套接字耗尽问题。针对上面问题,继续对HttpClient 改进。

方法3

这里我们使用单例模式试一试。代码如下:

public class HttpClientTestController : ControllerBase
    {
        private static HttpClient _httpClient;
        static HttpClientTestController()
        {
            _httpClient = new HttpClient();
        }
        //注意:有许多方法可以实现单例模式。在这里使用了静态实例方法。
        [HttpGet]
        public async Task<string> TestHttpClient()
        {
            var url = "https://localhost:7281/WeatherForecast";
            #region 版本3
            //var response = await _httpClient.GetAsync(url);
            //return await response.Content.ReadAsStringAsync();
            #endregion
        }
    }

 代码编写完成后我们再试一试,结果如下:

 

 

因为使用了单例模式,没有创建新实例使用了相同的连接。这种方法解决了套接字耗尽问题。但是,我们注意到有一个状态为“已建立”的开放连接。如果有DNS更改或与网络相关的更改可能会影响连接,应用程序可能会失败,需要重新启动应用程序才能解决。这个方法也不是最理想的。

方法4

HttpClient是.NET内置方法,这里可以通过使用 IHttpClientFactory 接口来实现,从而避免上面的问题。代码如下:

public class HttpClientTestController : ControllerBase
    {
        private readonly IHttpClientFactory _httpClientFactory;
        public HttpClientTestController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }
        [HttpGet]
        public async Task<string> TestHttpClient()
        {
            var url = "https://localhost:7281/WeatherForecast";
            #region 版本4
            var httpClient = _httpClientFactory.CreateClient();
            var response = await httpClient.GetAsync(url);
            return await response.Content.ReadAsStringAsync();
            #endregion
        }

 使用IHttpClientFactory 的话,需要在Program.cs 中注入,代码如下:

builder.Services.AddHttpClient();

 同样多次请求,然后执行netstat命令。效果如下:

 

 

从请求的状态来看,通过使用 _httpClientFactory.CreateClient() 完美解决问题。

总结

本文用四种方法渐进讲述了HttpClient的使用方法以及在使用过程中的问题,最终用IHttpClientFactory解决了出现的问题。希望本文对你有所收获,欢迎留言或者吐槽。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/475082.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法之时间复杂度---数据结构

目录 前言&#xff1a; 1.时间复杂度 1.1时间复杂度的理解 1.2规模与基本操作执行次数 1.3大O渐进表示法 1.4计算基本操作的次数 2.常见的时间复杂度及其优劣比较 ❤博主CSDN&#xff1a;啊苏要学习 ▶专栏分类&#xff1a;数据结构◀ 学习数据结构是一件有趣的事情&…

2023五一数学建模B题完整模型代码【原创首发】

已经完成五一数学建模全部内容&#xff0c;大家可以文末查看&#xff01;&#xff01;供参考使用&#xff01; 摘要 随着网络购物的普及和发展&#xff0c;快递行业需求持续增长&#xff0c;对于快递公司来说&#xff0c;准确预测运输需求以及合理规划运输线路和仓库布局变得…

分享一个有意思的键盘,我们就只会ctrl c+v

先上效果图&#xff1a; 再上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>* {border: 0;box-sizing: border-box;margin: 0;padding: 0;}:roo…

【pyTorch学习笔记④】PyTorch基础·中篇

文章目录 三、Numpy与Tensor3.Tensor的索引4.Tensor的广播机制5.逐元素操作6.归并操作7.比较操作8.矩阵操作9.PyTorch与Numpy的比较 相关推荐 三、Numpy与Tensor 3.Tensor的索引 &#xff08;1&#xff09;item&#xff1a;若Tensor为单元素&#xff0c;则返回标量&#xff0…

驱动开发:通过MDL映射实现多次通信

在前几篇文章中LyShark通过多种方式实现了驱动程序与应用层之间的通信&#xff0c;这其中就包括了通过运用SystemBuf缓冲区通信&#xff0c;运用ReadFile读写通信&#xff0c;运用PIPE管道通信&#xff0c;以及运用ASYNC反向通信&#xff0c;这些通信方式在应对一收一发模式的时…

【Java笔试强训 8】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;两种排…

【Java笔试强训 6】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;不要二 …

权限提升:本地权限提升.(AT || SC || PS )

权限提升&#xff1a;本地权限提升. 权限提升简称提权&#xff0c;由于操作系统都是多用户操作系统&#xff0c;用户之间都有权限控制&#xff0c;比如通过 Web 漏洞拿到的是 Web 进程的权限&#xff0c;往往 Web 服务都是以一个权限很低的账号启动的&#xff0c;因此通过 Web…

JavaScript用map实现Hashmap

&#x1f4dd;个人主页&#xff1a;爱吃炫迈 &#x1f48c;系列专栏&#xff1a;数据结构与算法 &#x1f9d1;‍&#x1f4bb;座右铭&#xff1a;道阻且长&#xff0c;行则将至&#x1f497; 文章目录 正如我们已经看到的&#xff0c;Map 对象是一个键值对。最初&#xff0c;M…

〖Python网络爬虫实战⑲〗- 数据存储之CSV文件

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…

第二部分——长难句——第二章——复合句——第一节——名词性从句

首先复合句是什么呢&#xff1f; 多件事一样重要就叫并列句&#xff0c;如果不一样重要就叫并列句。 复合句主句从句 下面我们来看一个例句&#xff1a; 找到从句之后剩下来的不就是主句吗&#xff1f; 一&#xff0c;宾语从句 &#xff08;一&#xff09;宾语从句的含义 一…

字符串中的第一个唯一字符

题目&#xff1a;字符串中的第一个唯一字符 思路一&#xff1a;暴力查找&#xff0c;时间复杂度 思路一&#xff1a;开辟检查重复数组,以空间换时间&#xff0c;时间复杂度 这段代码的作用是在一个字符串 s 中找到第一个不重复&#xff08;只出现一次&#xff09;的字符&#…

kafka和rocketmq区别对比

Kafka和RocketMQ是目前非常流行的分布式消息系统&#xff0c;它们都能够高效地处理海量的消息数据。在本文中&#xff0c;我们将对Kafka和RocketMQ进行技术比较&#xff0c;分析它们在各方面的优缺点&#xff0c;以便读者在选择消息系统时能够做出更加明智的决策。 一、架构设计…

Java-volatile实现详解(从java到汇编)

在Java内存模型一节&#xff0c;除了synchronized外&#xff0c;我们还提到一个常用关键词----volatile&#xff0c;我们说过volatile保证了并发环境的可见性和顺序性&#xff0c;使用volatile修饰的变量&#xff0c;当然值发生改变时&#xff0c;可以同步到其他线程&#xff0…

【python】你的表情包缺不缺?我猜你缺了~来批量获取一波吧~

目录 前言环境使用:模块使用:如何去实现本次案例: <通用模板>代码展示尾语 &#x1f49d; 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 在我们的生活中&#xff0c;总少不了表情包来调剂 少了表情包就会少了很多趣味 今天就来教大家如何批量下载我们的表情包 环…

力扣刷题2023-04-29-1——题目:1431. 拥有最多糖果的孩子

题目&#xff1a; 给你一个数组 candies 和一个整数 extraCandies &#xff0c;其中 candies[i] 代表第 i 个孩子拥有的糖果数目。 对每一个孩子&#xff0c;检查是否存在一种方案&#xff0c;将额外的 extraCandies 个糖果分配给孩子们之后&#xff0c;此孩子有 最多 的糖果…

接触Word的编辑保护【简单版】

首先&#xff0c;我们遇到的情况是下图这样的&#xff1a; 点一下停止保护&#xff0c;是下图这样的&#xff1a; 开始解决&#xff1a; 第一种方式&#xff1a;另存为Word Xml 存好了&#xff0c; 打开如下图&#xff08;我用VS打开的&#xff0c;最好找个能够格式化代码的编…

秘密是如何被泄露的?自建文件分享神器HFS

近年来&#xff0c;随着互联网技术的飞速发展&#xff0c;我们对于互联网的依赖也日益增加。利用互联网这种高效便捷的工具&#xff0c;我们可以随时随地进行文件的传输、图片的分享以及与他人的交流。然而&#xff0c;看似安全的聊天窗口&#xff0c;其实背后是庞大的互联网算…

MybatisPlus动态表名

核心代码 mybatisplus的配置 Configuration public class MybatisPlusConfig {// 这里是存储需要动态变化的表&#xff0c;防止乱操作static List<String> tableList() {List<String> tables new ArrayList<>();//表名tables.add("user");return…

Flask框架的学习---01

1.工程搭建&#xff1a; 安装flask: pip3 install flask 终端运行&#xff1a;flask run 绑定IP地址和端口&#xff1a;Flask run -h 127.0.0.1 -p 8083 修改端口号生产环境&#xff1a;set FLASK_ENVproduction开发模式&#xff1a;set FLASK_ENVdevelopment 虽然 flask …