对于 HttpClient 的请求响应值 HttpResponseMessage 来说,既然继承了 IDisposable 接口,自然就是想让大家可以通过 using 或者手动调用 Dispose 进行释放的。本文将来聊聊对 HttpResponseMessage 调用 Dispose 进行释放的意义有多大,有没有必要性的问题

先说结论,建议通过 using 或者手动调用 Dispose 释放 HttpResponseMessage 对象。 但不直接或间接调用 Dispose 释放也没有出现什么大问题,也不会出现重大的内存泄露问题

在 HttpResponseMessage 的终结器(析构)里面也会自动调用 Dispose 释放资源,也就是在 HttpResponseMessage 对象被 GC 时候,也会能够调用到 Dispose 的逻辑

调用 HttpResponseMessage 的 Dispose 的意义在于释放 HttpResponseMessage 的 Content 资源。更细分的需要聊到请求对应的 HTTP 版本。对于 HTTP 1.1 版本来说,调用 Dispose 方法约等于啥都没做,约等于标记状态而已,调用或不调用约等于没有差别

对于 HTTP 2 来说,直接或间接调用 HttpResponseMessage 的 Dispose 方法可以提升整体的性能。原因是在 HttpResponseMessage 的 Dispose 方法里面,将会释放 HttpResponseMessage 的 Content 所使用的数组池的资源,让 Content 里的缓存数组返回给到数组池,方便其他业务逻辑复用。其次在 Content 还没被读取完成的时候,调用 Dispose 方法能够让 HTTP 连接归还连接池,方便后续其他逻辑复用连接。而在 Content 被读取完成时,自然连接就还给了连接池,此时调用 Dispose 方法将没有连接池的优化。但无论如何,直接或间接调用 HttpResponseMessage 的 Dispose 方法,还是有一定的提升的,至少还能归还 Content 里的缓存数组到数组池

总的来说,推荐使用 using 关键字释放 HttpResponseMessage 对象。至少这样写起来不亏

对 HttpResponseMessage 直接或间接调用 Dispose 方法,将会自动调用到 HttpResponseMessage 的 Content 的释放,也就是从 Content 里所获取的 Stream 可以不用再释放。当然,同时对 Content 里所获取的 Stream 和 HttpResponseMessage 都调用释放也没有什么问题,如以下代码是没有问题的,框架内部处理了

            using HttpResponseMessage response = Xxx();
using var stream = response.Content.ReadAsStream();

只对 HttpResponseMessage 或者是 Content 里所获取的 Stream 进行释放,其中之一调用 Dispose 释放效果约等于相同。这是因为在 HttpResponseMessage 的 Dispose 里面最重要的就是调用 Content 的释放,因此只对 Content 调用释放也是完全合理的

感谢 lsj 阅读 dotnet 源代码然后告诉我,让我的代码有了基础的支持。同时也需要吐槽一下官方文档对此行为没有写清楚,让我以为调用 Dispose 会断开连接,导致连接无法还连接池。实际上是在 HTTP 2 调用 Dispose 会更好的还给连接池

至于对 Content 里所获取的 Stream 调用 await using 进行异步释放,这是没有必要的,因为这里的释放逻辑没有什么需要异步的。虽然加了也不亏

dotnet 是否应该对 HttpResponseMessage 调用 Dispose 进行释放的更多相关文章

  1. 析构函数中调用 Dispose 报错 :Internal .Net Framework Data Provider error 1.[非原创]

    搜索MSDN的资源可以找到答案: 原文如下http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=473449&SiteID=1 以下是关于 ...

  2. Python/dotNET Redis服务连接客户端调用SET方法的同时获取Redis服务器返回的内容

    在用Python或dotNET redis客户端连接redis服务器的时候,当你调用客户端的SET方法后同时还想得到其返回的字符串,那么需要处理一下. 1. Redis Python redis客户端 ...

  3. HttpResponseMessage 调用.net web api

    // // GET: /Home/ //释迦苦僧 public ActionResult Index() { HttpClient client = new HttpClient(); client. ...

  4. Dispose模式释放非托管资源

    实现方式用的是设计模式里的模板模式,基类先搭好框架,子类重写void Dispose(bool disposing) 即可. 需要注意的是基类的Finalize函数也就是析构函数调用的是虚函数void ...

  5. 【Win 10 应用开发】Sqlite 数据库的简单用法

    如果老周没记错的话,园子里曾经有朋友写过如何在 UWP 项目中使用 Sqlite数据库的文章.目前我们都是使用第三方封装的库,将来,SDK会加入对 Sqlite 的支持. 尽管目前 UWP-RT 库中 ...

  6. 【.net 深呼吸】自定义缓存配置(非Web项目)

    在前一篇烂文中,老周简单讲述了非Web应用的缓存技术的基本用法.其实嘛,使用系统默认方案已经满足我们的需求了,不过,如果你真想自己来配置缓存,也是可以的. 缓存的自定义配置可以有两种方案,一种是用代码 ...

  7. Drools API的使用学习

    Drools API的使用学习在 Drools 当中,规则的编译与运行要通过 Drools 提供的各种 API 来实现,这些 API 总体来讲可以分为三类:规则编译.规则收集和规则的执行.完成这些工作 ...

  8. mui日期插件$, each遍历,EventListener事件监听,json格式

    (function($) { $.init(); var result = $('#result')[0]; var btns = $('.btn'); btns.each(function(i, b ...

  9. using语法糖

    资源的分类 首先说一下资源的分类: 托管资源:由CLR管理分配和释放资源 非托管资源:不受CLR管理的对象,如 文件(StreamReader,BinaryReader,DataTable,各种Str ...

  10. visual studio installer制作安装包——Installer 类

    链接:https://msdn.microsoft.com/zh-cn/library/system.configuration.install.installer.aspx Installer 类 ...

随机推荐

  1. 记录-VUE中常用的4种高级方法

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 1. provide/inject provide/inject 是 Vue.js 中用于跨组件传递数据的一种高级技术,它可以将数据注入到 ...

  2. Web Audio API 第3章 音量和响度

    此章介绍的科普物理声音知识相当有用,编程的反而涉及的少 音量和响度 Loudness 响度 注:根据<韦氏词典>,响度是"一种声音的属性,它决定了所产生的听觉感觉的大小,主要取决 ...

  3. 第十三届蓝桥杯大赛软件赛省赛【Java 大学B 组】试题C: 字符统计

    1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String args[]) { 5 Sca ...

  4. 从优秀到卓越:成为DevOps专家的7项软技能

    在我的职业生涯中,遇见过许多专业人士,他们在技术上非常健全,对自己的领域和技术有很好的掌握和专业知识,但是由于缺乏软技能,他们错过了晋升.现场机会.高级技术面试以及职业生涯中的机会.很震惊吧,技术好却 ...

  5. ET介绍——浅谈AI框架

    AI框架 1. 几种AI的设计 AI在游戏中很多,但是为什么大家总是感觉ai编写起来十分困难,我后来思考了一番,主要原因是使用的方法不当.之前大家编写ai主要有几种方案: a. 状态机 我是不知道谁想 ...

  6. ASCII编码的全面介绍

    1. ASCII编码的定义和历史 ASCII(American Standard Code for Information Interchange)是一种用于将文本字符转换为数字编码的标准,最初由美国 ...

  7. #期望,树的直径#51nod 1803 森林直径

    题目 有一棵 \(n\) 个结点的树,按顺序给出树边 \((fa[i],i)\), \(Q\) 次询问查询如果只选取第 \([l,r]\) 条树边,问森林的直径 \(fa[i]\) 的生成方式为 \( ...

  8. #倍增,floyd#CF147B Smile House

    题目 求一张有向图的最小正环(环上结点数最小) 分析 有环当且仅当 \(f[i][i]\) 为正数, 那么考虑跑 \(n\) 次 floyd 直接转移,时间复杂度为 \(O(n^4)\) 然而没必要这 ...

  9. AtCoder Beginner Contest 220

    传送门 A.B.C.D.F比较简单,没必要写出来 E - Distance on Large Perfect Binary Tree 题目 问一个深度为 \(n\)的满二叉树有多少个点对的距离恰好为 ...

  10. #树链剖分,树上启发式合并#CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    题目 分析 考虑回文串当且仅当最多有一个字母出现奇数次, 可以记录某个二进制状态的最大深度, 一种就是点\(x\)到某个点,另一种就是经过点\(x\)的一条路径 在\(x\)的子树中递归实现,重儿子保 ...