.NET Core开发实战(第6课:作用域与对象释放行为)--学习笔记(下)
06 | 作用域与对象释放行为
接下来,把服务切换为单例模式,通过工厂的方式
services.AddSingleton<IOrderService>(p => new DisposableOrderService());
启动程序,输出如下:
=======1==========
=======2==========
接口请求处理结束
可以看到代码实际上不会被释放
如果切换为瞬时模式,通过工厂的方式
services.AddTransient<IOrderService>(p => new DisposableOrderService());
启动程序,输出如下:
=======1==========
DisposableOrderService Disposed:12021664
=======2==========
接口请求处理结束
DisposableOrderService Disposed:3165221
DisposableOrderService Disposed:13048313
这里可以看到,获取三个服务并且释放掉
接下来把服务调整为自己创建,并注册进去
var service = new DisposableOrderService();
services.AddSingleton<IOrderService>(service);
同样我们也不会得到释放的输出
也就是说,通过这种方式注册,容器不会管理对象的生命周期
如何识别这个区别呢?
在控制器中注入 IHostApplicationLifetime 接口
这个接口的作用是用来管理整个应用程序的生命周期
它有一个方法 StopApplication
也就是说它可以把整个应用程序关掉
接着,通过手工关掉的方式看一下应用程序关闭时会不会把单例对象释放掉
[HttpGet]
public int Get([FromServices] IOrderService orderService,
[FromServices] IOrderService orderService2,
[FromServices]IHostApplicationLifetime hostApplicationLifetime,
[FromQuery]bool stop = false)
{
Console.WriteLine("=======1==========");
// HttpContext.RequestServices 是当前请求的一个根容器,应用程序根容器的一个子容器,每个请求会创建一个容器
using (IServiceScope scope = HttpContext.RequestServices.CreateScope())
{
// 在这个子容器下面再创建一个子容器来获取服务
var service = scope.ServiceProvider.GetService<IOrderService>();
var service2 = scope.ServiceProvider.GetService<IOrderService>();
}
Console.WriteLine("=======2==========");
if (stop)
{
hostApplicationLifetime.StopApplication();
}
Console.WriteLine("接口请求处理结束");
return 1;
}
首先用自己创建对象的方式
var service = new DisposableOrderService();
services.AddSingleton<IOrderService>(service);
启动程序
输入 ?stop=true
https://localhost:5001/weatherforecast?stop=true
输出如下:
...
DependencyInjectionScopeAndDisposableDemo.exe (进程 16884)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
如果单例由容器来管理,切换回普通注册方式
services.AddSingleton<IOrderService, DisposableOrderService>();
启动程序
输入 ?stop=true
https://localhost:5001/weatherforecast?stop=true
输出如下:
Application is shutting down...
接口请求处理结束
DisposableOrderService Disposed:23399238
对象释放,应用程序退出
这里说明单例的服务都是注册在根容器里面
根容器的释放意味着需要在整个应用程序退出时释放
这个时候它会释放自己所管理的所有的 IDisposable 的对象
这里面有一个非常需要注意的坑:
假如把服务注册成瞬时的
services.AddTransient<IOrderService, DisposableOrderService>();
然后又在根容器里面去获取这个对象
var s = app.ApplicationServices.GetService<IOrderService>();
这意味着在根容器去持续的创建 IOrderService,但是由于根容器只会在应用程序整个退出时回收,也就意味着这些对象会一直积累在应用程序内
调整控制器,不获取 IOrderService
[HttpGet]
public int Get(
[FromServices]IHostApplicationLifetime hostApplicationLifetime,
[FromQuery]bool stop = false)
{
if (stop)
{
hostApplicationLifetime.StopApplication();
}
return 1;
}
仅仅在根容器获取一次
var s = app.ApplicationServices.GetService<IOrderService>();
这样运行起来,每次请求(点击刷新)的话,整个输出是不会有内容的,因为我们没有在子容器里面去获取对象
也就是说,实现了 IDisposable 接口的服务,如果时注册瞬时的,又在根容器去做操作,它会一直保持到应用程序退出的时候,才能够被回收掉
GitHub源码链接:
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
.NET Core开发实战(第6课:作用域与对象释放行为)--学习笔记(下)的更多相关文章
- 《Flask Web开发实战:入门、进阶与原理解析》 学习笔记
一个视图函数可以绑定多个 URL 为了让互联网上的人都可以访问,需要安装程序的服务器有公网ip 如果过度使用扩展,在不需要 的地方引人,那么相应也会导致代码不容易维护 ,应该尽量从实际需求出发,只在需 ...
- 2月送书福利:ASP.NET Core开发实战
大家都知道我有一个公众号“恰童鞋骚年”,在公众号2020年第一天发布的推文<2020年,请让我重新介绍我自己>中,我曾说到我会在2020年中每个月为所有关注“恰童鞋骚年”公众号的童鞋们送一 ...
- [ASP.NET Core开发实战]开篇词
前言 本系列课程文章主要是学习官方文档,再输出自己学习心得,希望对你有所帮助. 课程大纲 本系列课程主要分为三个部分:基础篇.实战篇和部署篇. 希望通过本系列课程,能让大家初步掌握使用ASP.NET ...
- .NET Core开发实战(第11课:文件配置提供程序)--学习笔记
11 | 文件配置提供程序:自由选择配置的格式 文件配置提供程序 Microsoft.Extensions.Configuration.Ini Microsoft.Extensions.Configu ...
- [ASP.NET Core开发实战]基础篇02 依赖注入
ASP.NET Core的底层机制之一是依赖注入(DI)设计模式,因此要好好掌握依赖注入的用法. 什么是依赖注入 我们看一下下面的例子: public class MyDependency { pub ...
- 2、SpringBoot接口Http协议开发实战8节课(1-6)
1.SpringBoot2.xHTTP请求配置讲解 简介:SpringBoot2.xHTTP请求注解讲解和简化注解配置技巧 1.@RestController and @RequestMapping是 ...
- [ASP.NET Core开发实战]基础篇03 中间件
什么是中间件 中间件是一种装配到应用管道,以处理请求和响应的组件.每个中间件: 选择是否将请求传递到管道中的下一个中间件. 可在管道中的下一个中间件前后执行. ASP.NET Core请求管道包含一系 ...
- [ASP.NET Core开发实战]基础篇01 Startup
Startup,顾名思义,就是启动类,用于配置ASP.NET Core应用的服务和请求管道. Startup有两个主要作用: 通过ConfigureServices方法配置应用的服务.服务是一个提供应 ...
- 2、SpringBoot接口Http协议开发实战8节课(7-8)
7.SpringBoot2.x文件上传实战 简介:讲解HTML页面文件上传和后端处理实战 1.讲解springboot文件上传 MultipartFile file,源自SpringMVC 1)静态页 ...
- [ASP.NET Core开发实战]基础篇06 配置
配置,是应用程序很重要的组成部分,常常用于提供信息,像第三方应用登录钥匙.上传格式与大小限制等等. ASP.NET Core提供一系列配置提供程序读取配置文件或配置项信息. ASP.NET Core项 ...
随机推荐
- 你真的懂Linux内核中的阻塞和异步通知机制吗?
@ 目录 阻塞/非阻塞简介 阻塞/非阻塞例程 等待队列简介 等待队列相关函数 定义等待队列 初始化等待队列头 定义并初始化一个等待队列项 将队列项添加到等待队列头 将队列项从等待队列头移除 等待唤醒 ...
- normalize.css——移动端css初始化推荐
保护了有价值的默认值 修复了浏览器bug 是模块化的 拥有详细的文档 https://www.jianshu.com/p/9d7ff89757fd
- 使用zipFile读取文件时遇到的问题及解决(KeyError: "There is no item named 'xxx' in the archive")
问题描述 在Windows上跑一段代码时,遇到如下问题: KeyError: "There is no item named 'CDR_Data\\\\CDR.Corpus.v010516\ ...
- Oracle表结构&数据类型&约束
1.Oracle 表结构 1.1.创建表名的规范 推荐以"t_xxx" 不能含有"+- "等非法字符,eg:sql create table "t-1 ...
- 百度网盘(百度云)SVIP超级会员共享账号每日更新(2024.01.08)
一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免 ...
- [转帖]堆表&索引组织表
堆表&索引组织表 https://zhuanlan.zhihu.com/p/487271927 15 人赞同了该文章 很多大佬强调学习一定要看"原版英文材料". 比如再 ...
- [转帖]Prometheus 监控之 Blackbox_exporter黑盒监测 [icmp、tcp、http(get\post)、dns、ssl证书过期时间]
Blackbox_exporter 主动监测主机与服务状态 Prometheus 官方提供的 exporter 之一,可以提供 http.dns.tcp.icmp 的监控数据采集 官方github: ...
- [转帖]linux中top性能分析工具中的TIME+
top命令的TIME/TIME+是指的进程所使用的CPU时间,不是进程启动到现在的时间,因此,如果一个进程使用的cpu很少,那即使这个进程已经存在N长时间,TIME/TIME+也是很小的数值. 此外, ...
- [转帖] TiDB 产品体系介绍
https://www.modb.pro/db/521269#:~:text=%E4%BC%81%E4%B8%9A%E7%89%88%E5%92%8C%E7%A4%BE%E5%8C%BA%E7%89% ...
- [转帖]认识目标文件的格式——a.out COFF PE ELF
https://cloud.tencent.com/developer/article/1446849 1.目标文件的常用格式 目标文件是源代码编译后未进行链接的中间文件(Windows的.obj ...