HttpClient

使用HttpClient可以很方便的请求Web API,但在使用时有一些需要注意的地方,不然会给你的程序带来毁灭性的问题。

HttpClient是一个继承了IDisposable接口的对象,所以在使用的时候,需要主动调用Dispose方法来释放它。或者使用using

using(var client = new HttpClient())
{
//do something with http client
}

  

这看起来似乎没什么问题。我们使用一些代码来测试一下它,我们将发起10个GET请求:

namespace ConsoleApplication
{
public class Program
{
public static async Task Main(string[] args)
{
Console.WriteLine("Starting connections");
for(int i = 0; i<10; i++)
{
using(var client = new HttpClient())
{
var result = await client.GetAsync("http://www.zkea.net");
Console.WriteLine(result.StatusCode);
}
}
Console.WriteLine("Connections done");
}
}
}

  

输出结果如下:

Starting connections
OK
OK
OK
OK
OK
OK
OK
OK
OK
OK
Connections done

  

看起来一切正常,但实际上并不是!我们使用netstat来查看一下sockets的使用情况:

C:\Users\wayne>NETSTAT.EXE
...
Proto Local Address Foreign Address State
TCP 10.211.55.6:12050 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12051 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12053 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12054 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12055 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12056 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12057 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12058 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12059 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12060 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12061 47.74.132.243:http TIME_WAIT
TCP 10.211.55.6:12062 47.74.132.243:http TIME_WAIT
...

  

虽然应用程序已经退出,但是刚才发起的连接仍处于 TIME_WAIT 状态。TIME_WAIT 状态是指连接已经在一边关闭,但仍在等待是否有其他数据包出现, 因为它们可能在网络上的某个地方被延迟,socket资源并没有立即被回收。所以,如果你的程序(网站)的并发量很大,而每一次都实例化一个HttpClient对象,你的程序将会消耗掉服务器上所有可用的socket资源,并导致程序出现异常,不可正常访问。

正确使用HttpClient

HttpClient里面的方法都是线程安全的:

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync

  

所以你应当只实例化一个HttpClient对象,并且不需要去主动释放它,它会在你程序退出的时候一起被释放掉。

我们对程序做以下修改再测试一下:

namespace ConsoleApplication
{
public class Program
{
private static HttpClient Client = new HttpClient();
public static async Task Main(string[] args)
{
Console.WriteLine("Starting connections");
for(int i = 0; i<10; i++)
{
var result = await Client.GetAsync("http://aspnetmonsters.com");
Console.WriteLine(result.StatusCode);
}
Console.WriteLine("Connections done");
Console.ReadLine();
}
}
}

  

再看看socket使用情况,这下就一切正常了:

TCP    10.211.55.6:12254      47.74.132.243:http  ESTABLISHED

  

原文链接:http://www.zkea.net/codesnippet/detail/post-122.html

.Net Core使用HttpClient请求Web API注意事项的更多相关文章

  1. 使用 HttpClient 请求 Web Api

    1.获取 post 请求 body 内容 [HttpPost] public string GetId() { //如果方法参数里面有 [FromBody],则需要重新调整内容指针,再进行读取. // ...

  2. Web API WinForm使用HttpClient呼叫Web API

    前言 之前几篇文章已经介绍了 Web 与 Web API 的使用方式,接下来将介绍如何在 Windows Form 呼叫 Web API 的方法,要在 WinForm 中使用 Web API 的话,除 ...

  3. 002.Create a web API with ASP.NET Core MVC and Visual Studio for Windows -- 【在windows上用vs与asp.net core mvc 创建一个 web api 程序】

    Create a web API with ASP.NET Core MVC and Visual Studio for Windows 在windows上用vs与asp.net core mvc 创 ...

  4. ASP.NET Core MVC中构建Web API

    在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能. 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文 ...

  5. WebApi系列~实际项目中如何使用HttpClient向web api发异步Get和Post请求并且参数于具体实体类型

    回到目录 本讲比较实际,在WEB端有一个Index和Create方法,用来从web api显示实体列表数据和向api插入实体对象,这就是以往的网站,只不过是把数据持久化过程放到了web pai上面,它 ...

  6. 从实体框架核心开始:构建一个ASP。NET Core应用程序与Web API和代码优先开发

    下载StudentApplication.Web.zip - 599.5 KB 下载StudentApplication.API.zip - 11.5 KB 介绍 在上一篇文章中,我们了解了实体框架的 ...

  7. ASP.NET Core 1.0开发Web API程序

    .NET Core版本:1.0.0-rc2Visual Studio版本:Microsoft Visual Studio Community 2015 Update 2开发及运行平台:Windows ...

  8. 使用HttpClient 调用Web Api

    C#4.5 添加了异步调用Web Api . 如果你的项目是4.5以上版本,可以直接参考官方文档. http://www.asp.net/web-api/overview/web-api-client ...

  9. 【ASP.NET Web API2】利用HttpClient调用Web API(TODO)

    参照: 在一个空ASP.NET Web项目上创建一个ASP.NET Web API 2.0应用 纯属记录一下遇到的问题: 我们利用HttpClient来调用自宿主方式寄宿的Web API.HttpCl ...

随机推荐

  1. win7/64+python3.4+pyinstall3+tkinter+smtp=图形界面群发邮件客户端

    #file:   GUI_MAIL.py#Date:   2016/01/07#Author: lao_wan import tkinterimport smtplibfrom email.mime. ...

  2. django-上下文渲染器,将后端内容提供给模板使用,自定义渲染器

    使用场景:当同一个类容需要出现在多个模板中, 上下文管理器就是将这个内容以字典的形式返回给所有模板,模板通过 {{ key }}取值. 结构:上下文管理器 文件名一般为context_processo ...

  3. 好记性不如烂笔头-linux学习笔记3mysql数据库导入导出

    1 数据库文件导出 mysqldump -uroot -p123456 test > 1.sql 2数据库文件导入 mysql -uroot -p123456 test <1.sql 3 ...

  4. (2/24) 快速上手一个webpack的demo

    写在前面:该部分的安装都是基于windows系统的,且此处的webpack的版本为:3.6.0. 1.安装webpack 1.1 安装方法: 用win+R打开运行对话框,输入cmd进入命令行模式.然后 ...

  5. 37.使用PreResultListener实现回调

    转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html 在进行本实例前请前复习:五.2自定义拦截器.因为PreResultListe ...

  6. win10 切换语言英文版

    win10 切换英文语言 start > right click>control panel> time Language>laguage>Add >English ...

  7. 如何设置mysql允许外网访问

    修改表,登录mysql数据库,切换到mysql数据库,使用sql语句查看"select host,user from user ;" console: >use mysql; ...

  8. HTTP 返回码 400

    400(错误请求)服务器不理解请求的语法 404表示页面不存在 返回500表示内部服务出错, 返回301表示资源永久性跳转 HTTP 500 – 内部服务器错误 HTTP 500.100 – 内部服务 ...

  9. 基于jquery-ui及bootstrap的可拖拽模态框

    可直接使用代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  10. 01-A-1: 计算