這個結果說明,Object Pool 中的對象都是直接new出來的,并沒有對一些屬性進行貶值操作,這個時候往往沒有太多實際意義。
因為DefaultPooledObjectPolicy
本來就是直接new了一個對象出來,很多時候,這并不是我們所期望的!
要想符合我們實際的使用,就要自己定義一個Policy!
下面來看看用法2
用法2
先定義一個Policy,實現 IPooledObjectPolicy 這個接口。T很自然就是我們的Demo類了。
public class DemoPooledObjectPolicy : IPooledObjectPolicy<Demo> { public Demo Create() { return new Demo { Id = 1, Name = "catcher", CreateTimte = DateTime.Now }; } public bool Return(Demo obj) { return true; } }
這里要實現Create和Return兩個方法。
見名知義,Create方法就是用來創(chuàng)建Demo對象的,Return方法就是將Demo對象扔回Object Pool的(有借有還)。
然后是用DemoPooledObjectPolicy去替換DefaultPooledObjectPolicy。
var demoPolicy = new DemoPooledObjectPolicy(); var defaultPoolWithDemoPolicy = new DefaultObjectPool<Demo>(demoPolicy,1); //借 item1 = defaultPoolWithDemoPolicy.Get(); //還 defaultPoolWithDemoPolicy.Return(item1); //借,但是不還 item2 = defaultPoolWithDemoPolicy.Get(); Console.WriteLine($"{item1.Id}-{item1.Name}-{item1.CreateTimte}"); Console.WriteLine($"{item2.Id}-{item2.Name}-{item2.CreateTimte}"); Console.WriteLine(item1 == item2); //創(chuàng)建一個新的 item3 = defaultPoolWithDemoPolicy.Get(); Console.WriteLine($"{item3.Id}-{item3.Name}-{item3.CreateTimte}"); Console.WriteLine(item3 == item1);
這里定義了對象池只保留一個對象。
由于從object pool中取出來之后,有一步還回去的操作,所以item1和item2應當是同一個對象。
從object pool中拿出了item2之后,它并沒有還回去,所以object pool會基于我們定義的Policy去創(chuàng)建一個新的對象出來。
下面是用法2的輸出結果:
1-catcher-09/17/2018 22:32:38
1-catcher-09/17/2018 22:32:38
True
1-catcher-09/17/2018 22:32:38
False
可以看到item1,item2和item3的各個屬性是一樣的,并且item1和item2確實是同一個對象。item3和item1并不是同一個。
用法3
除了DefaultObjectPool外,還有DefaultObjectPoolProvider也可以創(chuàng)建一個Object Pool。
創(chuàng)建一個Object Pool,一定是離不開Policy的,所以這里還是用了我們自己定義的DemoPooledObjectPolicy。
var defaultProvider = new DefaultObjectPoolProvider(); var policy = new DemoPooledObjectPolicy(); //default maximumRetained is Environment.ProcessorCount * 2 ObjectPool<Demo> pool = defaultProvider.Create(policy); item1 = pool.Get(); pool.Return(item1); item2 = pool.Get(); Console.WriteLine($"{item1.Id}-{item1.Name}-{item1.CreateTimte}"); Console.WriteLine($"{item2.Id}-{item2.Name}-{item2.CreateTimte}"); Console.WriteLine(item1 == item2); item3 = pool.Get(); Console.WriteLine($"{item3.Id}-{item3.Name}-{item3.CreateTimte}"); Console.WriteLine(item3 == item2);
用Provider創(chuàng)建Object Pool時,不能指定保留的最大對象數量,只能用的是默認的Environment.ProcessorCount * 2。
后面的使用,和用法2是一樣的。
可以看到item1和item2是同一個對象。從Object Pool中取對象的時候,會取第一個,所以還回去后,再取的話,還是會取到原來的第一個。
item3那里是直接從Object Pool中取出來的,沒有再次創(chuàng)建,因為這里的Object Pool維護著多個對象,而不是用法2中的只有一個,所以它是直接從Pool中拿的。
下面是輸出結果
1-catcher-09/17/2018 22:38:34
1-catcher-09/17/2018 22:38:34
True
1-catcher-09/17/2018 22:38:34
False
和用法2,本質是一樣的。
用法4
好像上面的用法,都不那么像我們正常使用的。我們還是需要依賴注入的。
那么我們最后就來看看怎么結合依賴注入吧。當然這里的本質還是離不開Policy和Provider這兩個東西。
IServiceCollection services = new ServiceCollection(); services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>(); services.AddSingleton(s => { var provider = s.GetRequiredService<ObjectPoolProvider>(); return provider.Create(new DemoPooledObjectPolicy()); }); ServiceProvider serviceProvider = services.BuildServiceProvider(); var pool = serviceProvider.GetService<ObjectPool<Demo>>(); item1 = pool.Get(); pool.Return(item1); item2 = pool.Get(); Console.WriteLine($"{item1.Id}-{item1.Name}-{item1.CreateTimte}"); Console.WriteLine($"{item2.Id}-{item2.Name}-{item2.CreateTimte}"); Console.WriteLine(item1 == item2); item3 = pool.Get(); Console.WriteLine($"{item3.Id}-{item3.Name}-{item3.CreateTimte}"); Console.WriteLine(item3 == item2);
我們首先需要完成對Provider的注冊,然后直接拿它的實例去創(chuàng)建一個Object Pool即可。
如果想在其他地方用,通過構造函數注入即可。
這里的結果也是和前面一樣的,沒什么好多說的。
總結
在這幾種用法中,我們最常用的應該是用法4。
但是無論那種用法,我們都需要了解,Object Pool離不開Pool,Policy和Provider這三個家伙。
有了這三個,或許我們就可以為所欲為了。
當然,它還提供了幾個特殊的東西,有興趣的可以去看看。
•LeakTrackingObjectPool
•StringBuilderPooledObjectPolicy
最后用一個腦圖結束本文。
以上所述是小編給大家介紹的.NET Core中Object Pool的多種用法詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com