ASP.NET Core中的對象池化技術(shù)詳解
寫在前面
Microsoft.Extensions.ObjectPool 是 ASP.NET Core 基礎(chǔ)結(jié)構(gòu)的一部分,當(dāng)對象的初始化成本較高,并且可能被頻繁使用時,才適合采用對象池技術(shù);被ObjectPool管理的對象不會進(jìn)入垃圾回收,使用時通過由實例對象實現(xiàn)的Get()方法,從對象池中借出對象,用完之后調(diào)用Return(T obj)方法,將對象還回去。也可以在Return(T obj)方法中設(shè)置判斷條件,僅允許特定的對象進(jìn)入對象池。
通過NuGet 獲取 Microsoft.Extensions.ObjectPool 類庫

代碼實現(xiàn)
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.ObjectPool;
using System.Security.Cryptography;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
// DefaultPooledObjectPolicy: 默認(rèn)的策略,繼承抽象類PooledObjectPolicy
builder.Services.TryAddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
builder.Services.TryAddSingleton<ObjectPool<ReusableBuffer>>(serviceProvider =>
{
var provider = serviceProvider.GetRequiredService<ObjectPoolProvider>();
var policy = new DefaultPooledObjectPolicy<ReusableBuffer>();
return provider.Create(policy);
});
builder.Services.TryAddSingleton<ObjectPool<Person>>(serviceProvider => {
var provider = serviceProvider.GetRequiredService<ObjectPoolProvider>();
var policy = new PersonPoolPolicy();
return provider.Create(policy);
});
builder.Services.TryAddSingleton<ObjectPool<StringBuilder>>(serviceProvider =>
{
var provider = serviceProvider.GetRequiredService<ObjectPoolProvider>();
var policy = new StringBuilderPooledObjectPolicy();
return provider.Create(policy);
});
var app = builder.Build();
// config middleware
app.UseMiddleware<BirthdayMiddleware>();
app.MapGet("/", () => "Hello rjcql!");
// return the SHA256 hash of a word
http://localhost:5128/hash/xxxx
app.MapGet("/hash/{word}", (string word, ObjectPool<ReusableBuffer> bufferPool) =>
{
var buffer = bufferPool.Get();
try
{
// Set the buffer data to the ASCII values of a word
for (var i = 0; i < word.Length; i++)
{
buffer.Data[i] = (byte)word[i];
}
Span<byte> hash = stackalloc byte[32];
SHA256.HashData(buffer.Data.AsSpan(0, word.Length), hash);
return "Hash: " + Convert.ToHexString(hash);
}
finally
{
// Data is automatically reset because this type implemented IResettable
bufferPool.Return(buffer);
}
});
app.MapGet("/create/{name}", (string name, ObjectPool<Person> personPool) =>
{
var person = personPool.Get();
try
{
person.Id = Guid.NewGuid().ToString("N");
var lastName = person.Name; // 這個是上一個對象的值
person.Name = name;
return $"{person.Id}:{person.Name}, {lastName}";
}
finally
{
// 根據(jù)條件回收
personPool.Return(person);
}
});
app.Run();
public class ReusableBuffer : IResettable
{
public byte[] Data { get; } = new byte[1024 * 1024]; // 1 MB
public bool TryReset()
{
Array.Clear(Data);
return true;
}
}
public class Person
{
public string Id { get; set; }
public string Name { get; set; }
}
public class PersonPoolPolicy : PooledObjectPolicy<Person>
{
public override Person Create()
{
return new Person { Id = "", Name = "rjcql" };
}
public override bool Return(Person p)
{
if (p.Name != "rjcql")
{
// 不允許其他名稱的對象放入對象池
return false;
}
return true;
}
}
/// <summary>
/// 創(chuàng)建中間件
/// </summary>
public class BirthdayMiddleware
{
private readonly RequestDelegate _next;
public BirthdayMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, ObjectPool<StringBuilder> builderPool)
{
var stringBuilder = builderPool.Get();
try
{
stringBuilder.Append("Hi");
// 在中間干點啥別的
// await context.Response.WriteAsync(stringBuilder.ToString());
await _next.Invoke(context);
}
finally // 即使出錯也要保證歸還對象
{
builderPool.Return(stringBuilder);
}
}
}調(diào)用示例




因為設(shè)置了回收條件,所以只有名字為rjcql的對象才會被回收,所以每次調(diào)用都先把rjcql對象取出。
到此這篇關(guān)于ASP.NET Core中的對象池化技術(shù)詳解的文章就介紹到這了,更多相關(guān).NET Core對象池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實現(xiàn)pdf導(dǎo)出 .Net導(dǎo)出pdf文件
這篇文章主要為大家詳細(xì)介紹了C#實現(xiàn)pdf導(dǎo)出 .Net導(dǎo)出pdf文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09
.net core部署到windows服務(wù)上的完整步驟
這篇文章主要給大家介紹了關(guān)于.net core部署到windows服務(wù)上的完整步驟,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用.net core具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
asp.net內(nèi)置對象 Response對象使用介紹
這篇文章主要介紹了asp.net內(nèi)置對象:Response對象使用介紹,對Response對象感興趣的小伙伴們可以參考一下2015-11-11
ASP.NET Core 2.0 使用支付寶PC網(wǎng)站支付實現(xiàn)代碼
這篇文章主要介紹了ASP.NET Core 2.0 使用支付寶PC網(wǎng)站支付實現(xiàn)代碼,需要的朋友可以參考下2017-10-10
sqlserver 批量數(shù)據(jù)替換助手V1.0版發(fā)布
前段時間網(wǎng)站被掛馬,數(shù)據(jù)庫表中很多文本字段都被加上了一段js腳本。修復(fù)完程序漏洞之后便開始著手清理這些被注入的數(shù)據(jù),其間參考了一些網(wǎng)上的方法,大都是寫一個存儲過程進(jìn)行一個表一個表逐一清理。2011-10-10
ASP.NET導(dǎo)出數(shù)據(jù)到Excel的實現(xiàn)方法
在做asp.net程序時涉及到數(shù)據(jù)顯示的時候多數(shù)會要求打印,而網(wǎng)頁上的打印格式往往又不能滿足需求,經(jīng)常用的方法就是導(dǎo)入到Excel以后再進(jìn)行打印。(仿佛這已經(jīng)是老生常談)今天在網(wǎng)上搜了一段打印的代碼,覺得不錯,需要打印的朋友可以看看。2013-07-07

