ASP.NET Core中的对象池化技术详解
脚本之家 / 编程助手:解决程序员“几乎”所有问题!
脚本之家官方知识库 → 点击立即使用
写在前面
Microsoft.Extensions.ObjectPool 是 ASP.NET Core 基础结构的一部分,当对象的初始化成本较高,并且可能被频繁使用时,才适合采用对象池技术;被ObjectPool管理的对象不会进入垃圾回收,使用时通过由实例对象实现的Get()方法,从对象池中借出对象,用完之后调用Return(T obj)方法,将对象还回去。也可以在Return(T obj)方法中设置判断条件,仅允许特定的对象进入对象池。
通过NuGet 获取 Microsoft.Extensions.ObjectPool 类库
代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.ObjectPool; using System.Security.Cryptography; using System.Text; var builder = WebApplication.CreateBuilder(args); // DefaultPooledObjectPolicy: 默认的策略,继承抽象类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 { // 根据条件回收 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> /// 创建中间件 /// </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); } } } |
调用示例
因为设置了回收条件,所以只有名字为rjcql的对象才会被回收,所以每次调用都先把rjcql对象取出。
到此这篇关于ASP.NET Core中的对象池化技术详解的文章就介绍到这了,更多相关.NET Core对象池内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
.net 获取浏览器Cookie(包括HttpOnly)实例分享
这篇文章介绍了.net 获取浏览器Cookie(包括HttpOnly)实例,有需要的朋友可以参考一下2013-10-10ASP.NET MVC遍历验证ModelState的错误信息
这篇文章介绍了ASP.NET MVC遍历ModelState错误信息的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2022-09-09
最新评论