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

前言

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
   //欢迎公众号:DOTNET开发跳槽

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

图片

在这里可以看到状态“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
        }
//欢迎公众号:DOTNET开发跳槽

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

builder.Services.AddHttpClient();

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

图片

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

结语

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

源码地址:https://github.com/xbhp/webapitest

参考:微软官方文档

来源公众号:DotNet开发跳槽

原文链接:https://www.cnblogs.com/xbhp/archive/2023/04/12/17309933.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:在.NET Core使用 HttpClient 的正确方式 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • C#实现快递api接口调用方法

    C#实现快递API接口调用方法 在使用快递API时,我们需要通过接口调用获取物流信息。本文将介绍如何使用C#实现快递API的接口调用。 步骤 1.注册快递API并获取API key 首先,我们需要在快递API平台上注册并获取API key。需要注意,在不同快递公司的API接口中,需要使用其对应的API key,否则将无法获取物流信息。 2.创建C#项目并引入…

    C# 2023年5月31日
    00
  • C# SaveFileDialog与OpenFileDialog用法案例详解

    C#SaveFileDialog与OpenFileDialog用法案例详解 SaveFileDialog SaveFileDialog用于显示一个保存文件的对话框。 基本用法 使用SaveFileDialog需要首先在程序中引用命名空间: using System.Windows.Forms; 然后创建一个SaveFileDialog对象,设置其属性,最后使…

    C# 2023年5月15日
    00
  • 通用的CRUD之LiteDB

    前言 你要开发一个系统,是不是首要任务是先建库,建表,建字段,既所谓的数据建模(听起来高大上一点,数据建模也确实是个烧脑的活),要费不少功夫。不知你是否遇到过这样的场景。A产品有3个测试参数,B产品有6个测试参数,而且值和类型都各不相同,用SQL你要怎么建表呢?有人会说这简单“参数名,参数值两列搞定”,NO!数据类型考虑了吗,数据量考虑了吗?有人又说”每个参…

    C# 2023年5月10日
    00
  • C#中Serializable序列化实例详解

    下面是关于“C#中Serializable序列化实例详解”的完整攻略,包含两个示例。 1. Serializable序列化简介 Serializable是C#中的一个特性,用于将对象序列化为二进制格式,以便在网络上传输或保存到文件中。在C#中,我们可以使用Serializable特性来标记一个类,以便将其序列化为二进制格式。以下是C#中Serializabl…

    C# 2023年5月15日
    00
  • C#实现文件分割和合并的示例详解

    C#实现文件分割和合并的示例详解 本文将详细讲解C#实现文件分割和合并的过程,主要包括文件分割和文件合并两个部分。 文件分割 文件分割指将一个较大的文件分割成多个小文件,可以方便数据的传输和存储。接下来我们将介绍两种文件分割的实现方法。 实现方法一 我们可以使用FileStream类来完成文件的读取和写入操作。具体实现步骤如下: 判断待分割的文件是否存在,如…

    C# 2023年6月6日
    00
  • C# 中将数值型数据转换为字节数组的方法

    将数值型数据转换成字节数组在 C# 中是一项常见的任务。处理二进制数据通常需要将二进制数据以原始字节数组的形式进行处理。这篇攻略将提供如何在 C# 中将数值型数据转换为字节数组的方法。 方法一:BitConverter.GetBytes 其中一个将数值型数据转换成字节数组的方法是通过使用 BitConverter 类。该方法可以将数值类型转换成一个字节数组,…

    C# 2023年6月7日
    00
  • C#中ref关键字的用法

    当在C#中需要传递一个变量时,使用传值或传引用的方法。传值方式传递的是变量的值,而传递引用时传递的是变量的地址。ref关键字可以用来在函数调用中传递变量的地址,此时函数内对该变量的任何修改都会影响到调用者。 下面是ref关键字在C#中的用法示例: 1. 在函数中修改变量的值 假设我们有一个函数,要求增加输入值的值,可以使用ref关键字来传递变量,以便在函数中…

    C# 2023年5月31日
    00
  • asp.net中调用oracle存储过程的方法

    调用Oracle存储过程是ASP.NET中经常用到的操作之一。下面我将尝试为您提供一份完整的攻略指导。 准备工作 在调用Oracle存储过程之前,您需要完成以下准备工作: 确认已经安装了Oracle Client,并且可以连接到Oracle数据库。 在Oracle数据库中创建一个存储过程。 调用存储过程 在ASP.NET中,调用Oracle存储过程有两种方法…

    C# 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部