ASP.NET Core 对象池化技术

写在前面

Microsoft.Extensions.ObjectPool 是 ASP.NET Core 基础结构的一部分,当对象的初始化成本较高,并且可能被频繁使用时,才适合采用对象池技术;被ObjectPool管理的对象不会进入垃圾回收,使用时通过由实例对象实现的Get()方法,从对象池中借出对象,用完之后调用Return(T obj)方法,将对象还回去。也可以在Return(T obj)方法中设置判断条件,仅允许特定的对象进入对象池。

通过NuGet 获取 Microsoft.Extensions.ObjectPool 类库

代码实现

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对象取出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/335474.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

市场复盘总结 20240119

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 昨日主题投资 连板进级率 11/39 28.2% 二进三&#xff1a; 进级率低 43% 最常用的二种方法&#xff1a; 方…

[AI]文心一言爆火的同时,ChatGPT-4.5的正确打开方式

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言4.5key价格泄漏ChatGPT4.0使用地址ChatGPT正确打开方式最新功能语音助手存档…

【PICO】【VRTK】PICO项目后打包后在头盔中运行时不追踪

【背景】 PICO项目打包后可以在头盔中运行&#xff0c;但是画面是贴脸移动的&#xff0c;无法发生有效的空间追踪。 【解决办法】 我的Unity版本是2021.3.30LTS&#xff0c;ProjectSettings中的NetFramework默认是2.1。改到NetFramework后再打包就正常了。

安捷伦N5222A网络分析仪26.5GHz

安捷伦N5222A网络分析仪 N5222A 是 Agilent 的 26.5 GHz 网络分析仪。网络分析仪是一种功能强大的仪器&#xff0c;可以以无与伦比的精度测量射频设备的线性特性。许多行业使用网络分析仪来测试设备、测量材料和监控信号的完整性。 附加功能&#xff1a; 10 MHz 至 26.5 GHz 2…

el-table样式错乱解决方案

bug&#xff1a; 图片的椭圆框住的地方&#xff0c;在页面放大缩小之后就对不齐了。 原因&#xff1a; 主要原因是当你对页面放大缩小的时候&#xff0c;页面进行了重构&#xff0c;页面的宽高及样式进行了变化&#xff0c;但是在这个更新的过程中&#xff0c;table的反应并没…

git使用的常用指令

git作为一个版本控制工具&#xff0c;和maven并合称为实习的两大杀手工具。今天我来给大家介绍一下git的常用指令&#xff0c;帮助大家在实习和多人协同开发的时候提供一些帮助。 找到git管理的文件夹 命令1 git init 这个命令是为了初始化本地库 命令2 查看当前的git状态…

怎么做表单链接_从表单链接到营销策略

从表单链接到营销策略&#xff1a;一场无与伦比的转化之旅 在数字营销的世界里&#xff0c;表单链接是一种至关重要的元素。它不仅是一个简单的链接&#xff0c;更是企业与潜在客户之间建立联系的桥梁。如何将表单链接巧妙地融入营销策略&#xff0c;让潜在客户转化为真正的客…

JUC并发编程-线程和进程、Synchronized 和 Lock、生产者和消费者问题

1、什么是JUC 源码 官方文档 面试高频问&#xff01; java.util 工具包、包、分类 业务&#xff1a;普通的线程代码 Thread Runnable Runnable 没有返回值、效率相比入 Callable 相对较低&#xff01; 2、线程和进程 线程、进程&#xff0c;如果不能使用一句话说出来的技术…

力扣36. 有效的数独

模拟 思路&#xff1a; 使用三个哈希表来存储数字个数 row[r][val] 用于存储第 r 行 val 1 的个数&#xff1b;column[c][val] 用于存储第 c 列 val 1 的个数&#xff1b; subboxes[i][j][val] 用于存储第 i 行、第 j 列个小九宫格 val 1 的个数&#xff0c;其中&#xff1…

论文笔记:基于CLIP引导学习的多模式假新闻检测

整理了ICME2023 Multimodal Fake News Detection via CLIP-Guided Learning&#xff09;论文的阅读笔记 背景模型实验 背景 对于我们这一代人来说&#xff0c;在线社交网络在很大程度上取代了以报纸和杂志为代表的传统信息交流方式。人们喜欢在社交媒体上寻找朋友或分享观点。然…

Linux系统安装NFS服务器

NFS是一种网络文件系统&#xff0c;英文全称Network File System&#xff0c;通过NFS可以让不同的主机系统之间共享文件或目录。通过NFS&#xff0c;用户可以直接在本地NFS客户端读写NFS服务端上的文件&#xff0c;是非常好的共享存储工具。本篇文章将介绍如何在CentOS7上安装N…

2024年【G2电站锅炉司炉】考试报名及G2电站锅炉司炉复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 G2电站锅炉司炉考试报名是安全生产模拟考试一点通生成的&#xff0c;G2电站锅炉司炉证模拟考试题库是根据G2电站锅炉司炉最新版教材汇编出G2电站锅炉司炉仿真模拟考试。2024年【G2电站锅炉司炉】考试报名及G2电站锅炉…

在WIN从零开始在QMUE上添加一块自己的开发板(一)

文章目录 一、前言二、源码编译&#xff08;一&#xff09;安装Msys2&#xff08;二&#xff09;配置GCC工具链&#xff08;三&#xff09;安装QEMU构建依赖&#xff08;四&#xff09;下载编译QEMU源码 二、QUME编程基础&#xff08;一&#xff09;QOM机制&#xff08;二&…

如何有效防爬虫?一文讲解反爬虫策略

企业拥抱数字化技术的过程中&#xff0c;网络犯罪分子的“战术”也更难以觉察&#xff0c;并且这些攻击越来越自动化和复杂&#xff0c;也更加难以觉察。在众多攻击手段中&#xff0c;网络爬虫是企业面临的主要安全挑战。恶意爬虫活动可能导致数据滥用、盗窃商业机密等问题&…

MySQL之索引结构

索引概述 索引是帮助MySQL高效获取数据的数据结构&#xff08;有序&#xff09;。 在数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引用&#xff08;指向&#xff09;数据&#xff0c;这样就可以在这些数据结构上实现…

Ubuntu使用docker-compose安装chatGPT

ubuntu环境搭建专栏&#x1f517;点击跳转 Ubuntu系统环境搭建&#xff08;十五&#xff09;——使用docker-compose安装chatGPT Welcome to the AI era! 使用docker compose安装 在/usr/local文件夹下创建chatgpt mkdir chatgpt创建docker-compose.yaml vim docker-compos…

springcloud OpenFeign服务接口调用

文章目录 代码下载地址OpenFeign简介OpenFeign使用步骤测试 OpenFeign超时控制超时设置&#xff0c;故意设置超时演示出错情况服务提供方8001故意写暂停程序服务消费方80添加超时方法PaymentFeignService服务消费方80添加超时方法OrderFeignController测试YML文件里需要开启Ope…

考研C语言刷编程题篇之分支循环结构基础篇(一)

目录 第一题 第二题 方法一&#xff1a;要循环两次&#xff0c;一次求阶乘&#xff0c;一次求和。 注意&#xff1a;在求和时&#xff0c;如果不将sum每次求和的初始值置为1&#xff0c;那么求和就会重复。 方法二&#xff1a; 第三题 方法一&#xff1a;用数组遍历的思想…

Windows给docker设置阿里源

windows环境搭建专栏&#x1f517;点击跳转 Windows系统的docker设置阿里源 文章目录 Windows系统的docker设置阿里源1.获得镜像加速器2.配置docker 由于我们生活在中国大陆&#xff0c;所以外网的访问总是那么慢又困难&#xff0c;用docker拉取几兆的小镜象还能忍受&#xff…

数据结构排序二叉树(下)

哎,调了几天深度学习模型,今天来更新排序二叉树 文章目录 前言 一、排序二叉树的结构定义 二、在排序二叉树添加数据 三、定义创建排序二叉树函数 四、查找一棵二叉排序树中的结点x的所在层数 五、删除二叉排序树中T关键字x的节点 六、查找二叉排序树中的所有小于key的关…