架構師_程序員

 找回密碼
 注冊[Register]

QQ登錄

只需一步,快速開始

查看: 214|回復: 0
打印 上一主題 下一主題

[.NET Core] .NET Core 中 Object Pool 詳解

[復制鏈接]
跳轉到指定樓層
樓主
發表于 2020-4-15 17:38:34 | 只看該作者
Microsoft.Extensions.ObjectPool 是 ASP.NET Core 基礎結構的一部分,該基礎結構支持在內存中保留一組對象以供重復使用,而不是允許對對象進行垃圾回收。
如果要管理的對象是,則你可能需要使用對象池:

  • 分配/初始化成本高昂。
  • 表示某些有限資源。
  • 使用可預測和頻繁。


復用,是一個重要的話題,也是我們日常開發中經常遇到的,不可避免的問題。

舉個最為簡單,大家最為熟悉的例子,數據庫連接池,就是復用數據庫連接。

那么復用的意義在那里呢?

簡單來說就是減少不必要的資源損耗。

除了數據庫連接,可能在不同的情景或需求下,還會有很多其他對象需要進行復用,這個時候就會有所謂的 Object Pool(對象池)。

小伙伴們應該也自己實現過類似的功能,或用ConcurrentBag,或用ConcurrentQueue,或用其他方案。

這也里分享一個在微軟文檔中的實現

How to: Create an Object Pool by Using a ConcurrentBag

https://docs.microsoft.com/en-us/dotnet/standard/collections/thread-safe/how-to-create-an-object-pool

當然,在.NET Core中,微軟已經幫我們實現了一個簡單的Object Pool。

首先,新建一個.net core的控制臺項目,使用nuget命令添加如下包:

所有的代碼如下:

用法一



在創建pool之前,我們要先定義一個Policy。這里直接用自帶的DefaultPooledObjectPolicy來構造。

對象池會有一個維護的最大數量,線程數。

通過pool對象的Get方法,從對象池中取出一個對象。

上面代碼運行結果

#1-464d2e03-604d-4451-b68a-8a3a2abdfccc-itsvse.com-1/1/0001 12:00:00 AM
#2-70122aa0-a949-4c63-b878-321efe64c234-itsvse.com-1/1/0001 12:00:00 AM
#3-de717815-796a-4349-a571-047acc125104-itsvse.com-1/1/0001 12:00:00 AM
#4-3a404341-a560-47f7-a3b0-0d477a8ae17f-itsvse.com-1/1/0001 12:00:00 AM
#5-51c96126-d424-4b58-b07c-6408e6c4cea6-itsvse.com-1/1/0001 12:00:00 AM
#6-7ea4d596-fd2a-43b3-959a-9e48da58a758-itsvse.com-1/1/0001 12:00:00 AM
#7-6874c64b-532d-4f92-a4fb-ff472da574a1-itsvse.com-1/1/0001 12:00:00 AM
#8-ca767674-2c07-4f26-975f-4711a31d795d-itsvse.com-1/1/0001 12:00:00 AM
#9-a9cd1859-a919-46a0-ae5d-85b6d3d11ccb-itsvse.com-1/1/0001 12:00:00 AM
#10-fe89ed8b-4dfd-4eef-b876-b2a60ee50958-itsvse.com-1/1/0001 12:00:00 AM
這個結果說明,Object Pool 中的對象都是直接new出來的,并沒有對一些屬性進行貶值操作,這個時候往往沒有太多實際意義。

因為DefaultPooledObjectPolicy本來就是直接new了一個對象出來,很多時候,這并不是我們所期望的!

要想符合我們實際的使用,就要自己定義一個Policy!

下面來看看用法2

用法二

Create方法就是用來創建Demo對象的,Return方法就是將Demo對象扔回Object Pool的(有借有還)。



這里定義了對象池只保留一個對象。

由于從object pool中取出來之后,有一步還回去的操作,所以item1和item2應當是同一個對象。

從object pool中拿出了item2之后,它并沒有還回去,所以object pool會基于我們定義的Policy去創建一個新的對象出來。

下面是用法2的輸出結果:

985b3232-0a45-4115-8480-ad3d42c0ae10-itsvse.com-4/15/2020 3:31:15 AM
985b3232-0a45-4115-8480-ad3d42c0ae10-itsvse.com-4/15/2020 3:31:15 AM
True
8912424a-15c5-4891-b625-25b17eee5c8b-itsvse.com-4/15/2020 3:31:15 AM
False
可以看到item1,item2和item3的各個屬性是一樣的,并且item1和item2確實是同一個對象。item3和item1并不是同一個。


用法三

可以看到item1和item2是同一個對象。從Object Pool中取對象的時候,會取第一個,所以還回去后,再取的話,還是會取到原來的第一個。



item3那里是直接從Object Pool中取出來的,沒有再次創建,因為這里的Object Pool維護著多個對象,而不是用法2中的只有一個,所以它是直接從Pool中拿的。

下面是輸出結果

f3cd5467-536b-4ffe-9c71-de53027b4869-itsvse.com-4/15/2020 3:33:58 AM
f3cd5467-536b-4ffe-9c71-de53027b4869-itsvse.com-4/15/2020 3:33:58 AM
True
b933b593-af6d-4ebe-b21b-e8784d124764-itsvse.com-4/15/2020 3:33:58 AM
False
和用法2,本質是一樣的。

用法四

好像上面的用法,都不那么像我們正常使用的。我們還是需要依賴注入的。

那么我們最后就來看看怎么結合依賴注入吧。當然這里的本質還是離不開Policy和Provider這兩個東西。



我們首先需要完成對Provider的注冊,然后直接拿它的實例去創建一個Object Pool即可。

如果想在其他地方用,通過構造函數注入即可。

這里的結果也是和前面一樣的,沒什么好多說的。

總結

但是無論那種用法,我們都需要了解,Object Pool離不開Pool,Policy和Provider這三個家伙。

有了這三個,或許我們就可以為所欲為了。

當然,它還提供了幾個特殊的東西,有興趣的可以去看看。

LeakTrackingObjectPool

StringBuilderPooledObjectPolicy





上一篇:Web Services Enhancements (WSE) 3.0 介紹
下一篇:visual studio 2013如何查找替換多行的內容?
帖子永久地址: 

架構師_程序員 - 論壇版權1、本主題所有言論和圖片純屬會員個人意見,與本論壇立場無關
2、本站所有主題由該帖子作者發表,該帖子作者與架構師_程序員享有帖子相關版權
3、其他單位或個人使用、轉載或引用本文時必須同時征得該帖子作者和架構師_程序員的同意
4、帖子作者須承擔一切因本文發表而直接或間接導致的民事或刑事法律責任
5、本帖部分內容轉載自其它媒體,但并不代表本站贊同其觀點和對其真實性負責
6、如本帖侵犯到任何版權問題,請立即告知本站,本站將及時予與刪除并致以最深的歉意
7、架構師_程序員管理員和版主有權不事先通知發貼者而刪除本文

碼農網,只發表在實踐過程中,遇到的技術難題,不誤導他人。
您需要登錄后才可以回帖 登錄 | 注冊[Register]

本版積分規則

免責聲明:
碼農網所發布的一切軟件、編程資料或者文章僅限用于學習和研究目的;不得將上述內容用于商業或者非法用途,否則,一切后果請用戶自負。本站信息來自網絡,版權爭議與本站無關。您必須在下載后的24個小時之內,從您的電腦中徹底刪除上述內容。如果您喜歡該程序,請支持正版軟件,購買注冊,得到更好的正版服務。如有侵權請郵件與我們聯系處理。

Mail To:help@itsvse.com

QQ|Archiver|手機版|小黑屋|架構師 ( 魯ICP備14021824號-2 )|網站地圖

GMT+8, 2020-7-11 10:40

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回復 返回頂部 返回列表
捕鸟达人老版