日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET Core开发实战(第6课:作用域与对象释放行为)--学习笔记(下)

發布時間:2023/12/4 asp.net 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core开发实战(第6课:作用域与对象释放行为)--学习笔记(下) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

06 | 作用域與對象釋放行為

接下來,把服務切換為單例模式,通過工廠的方式

services.AddSingleton<IOrderService>(p => new DisposableOrderService());

啟動程序,輸出如下:

=======1========== =======2========== 接口請求處理結束

可以看到代碼實際上不會被釋放

如果切換為瞬時模式,通過工廠的方式

services.AddTransient<IOrderService>(p => new DisposableOrderService());

啟動程序,輸出如下:

=======1========== DisposableOrderService Disposed:12021664 DisposableOrderService Disposed:32106157 =======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>();

這樣運行起來,每次請求(點擊刷新)的話,整個輸出是不會有內容的,因為我們沒有在子容器里面去獲取對象

但實際上當我們退出的時候,會發現確實有一個實例被釋放掉了

DisposableOrderService Disposed:7511460

也就是說,實現了 IDisposable 接口的服務,如果時注冊瞬時的,又在根容器去做操作,它會一直保持到應用程序退出的時候,才能夠被回收掉

總結

以上是生活随笔為你收集整理的.NET Core开发实战(第6课:作用域与对象释放行为)--学习笔记(下)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。