Skip to content
forked from 2881099/IdleBus

IdleBus 空闲对象管理容器,有效组织对象重复利用,自动创建、销毁,解决【实例】过多且长时间占用的问题。

Notifications You must be signed in to change notification settings

nodyang/IdleBus

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IdleBus 空闲对象管理容器,有效组织对象重复利用,自动创建、销毁,解决【实例】过多且长时间占用的问题。有时候想做一个单例对象重复使用提升性能,但是定义多了,有的又可能一直空闲着占用资源。

专门解决:又想重复利用,又想少占资源的场景。

快速开始

dotnet add package IdleBus

class Program
{
    static void Main(string[] args)
    {
        //超过20秒没有使用,就销毁【实例】
        var ib = new IdleBus(TimeSpan.FromSeconds(20));
        ib.Notice += (_, e) =>
        {
            Console.WriteLine("    " + e.Log);

            if (e.NoticeType == IdleBus<IDisposable>.NoticeType.AutoRelease)
                Console.WriteLine($"    [{DateTime.Now.ToString("g")}] {e.Key} 空闲被回收");
        };

        while (true)
        {
            Console.WriteLine("输入 > ");
            var line = Console.ReadLine().Trim();
            if (string.IsNullOrEmpty(line)) break;

            // 注册
            ib.TryRegister(line, () => new TestInfo());

            // 第一次:创建
            TestInfo item = ib.Get(line) as TestInfo;

            // 第二次:直接获取,长驻内存直到空闲销毁
            item = ib.Get(line) as TestInfo;
        }

        ib.Dispose();
    }

    class TestInfo : IDisposable
    {
        public void Dispose() { }
    }
}

输出:

输入 >
aa1
    aa1 注册成功,0/1
    aa1 实例+++创建成功,耗时 0.1658ms,1/1
    aa1 实例获取成功 1次
    aa1 实例获取成功 2次
输入 >
aa2
    aa2 注册成功,1/2
    aa2 实例+++创建成功,耗时 0.0065ms,2/2
    aa2 实例获取成功 1次
    aa2 实例获取成功 2次
输入 >
aa3
    aa3 注册成功,2/3
    aa3 实例+++创建成功,耗时 0.0073ms,3/3
    aa3 实例获取成功 1次
    aa3 实例获取成功 2次
输入 >
    aa1 ---自动释放成功,耗时 0.7607ms,2/3
    [2020/1/7 14:22] aa1 空闲被回收
    aa2 ---自动释放成功,耗时 0.0289ms,1/3
    [2020/1/7 14:22] aa2 空闲被回收
    aa3 ---自动释放成功,耗时 0.0046ms,0/3
    [2020/1/7 14:22] aa3 空闲被回收

API

new IdleBus 可使用任何 IDisposable 实现类【混合注入】

new IdleBus<T> 可【自定义类型】注入,如: new IdleBus<IFreeSql>()

Method 说明
void Ctor() 创建空闲容器
void Ctor(TimeSpan idle) 指定空闲时间,创建空闲容器
IdleBus Register(string key, Func<T> create) 注册(其类型必须实现 IDisposable)
IdleBus Register(string key, Func<T> create, TimeSpan idle) 注册,单独设置空间时间
T Get(string key) 获取【实例】(线程安全),key 未注册时,抛出异常
List<T> GetAll() 获得所有【实例】(线程安全)
bool Exists(string key) 判断 key 是否已注册
void Remove(string key) 删除已注册的
int Quantity 注册数量
int UsageQuantity 已创建【实例】数量
event Notice 容器内部的变化通知,如:自动释放、自动创建

注意:Register 参数 create 属于对象创建器,切莫直接返回外部创建好的对象

var obj = new Xxx();
ib.Register("key01", () => obj); //错了,错了,错了

ib.Register("key01", () => new Xxx()); //正确

设计思路

IdleBus 和对象池不同,对象池是队列设计,我们是 KV 设计。

IdleBus 又像缓存,又像池,又像容器,无法具体描述。

1、注册:向容器中注册对象,指定 key + 创建器 + 空闲时间,可以注册和管理任何实现 IDisposable 接口对象

2、获取对象:开发人员使用 key 作为参数调用方法获得对象

  • 存在时,直接返回
  • 不存在时,创建对象(保证线程安全)

3、过期销毁:当容器中有实例运行,会启用后台线程定时检查,超过空闲时间设置的将被释放(Dispose)

使用场景

  • 多租户按数据库区分的场景,假设有1000个租户;
  • Redis 客户端需要操作 N 个 服务器;
  • Socket 长连接闲置后自动释放;
  • 管理 1000个 rabbitmq 服务器的客户端;
  • IdleScheduler 利用 IdleBus 实现的轻量定时任务调度;
  • 等等等。。。

举例:向 1000个 (不同的、不同的、不同的) rabbitmq 服务器发送消息,正常有两种做法:

1、定义 1000 个静态 client 一直 open 着,重复利用

缺点:1000个里面不是每个都活跃,然后也一直占用着资源

2、每次发送消息的时候 open,使用完再 close

new client("mq_0001server").pub(...).close();
new client("mq_0002server").pub(...).close();
new client("mq_0003server").pub(...).close();
new client("mq_0004server").pub(...).close();

缺点:性能损耗会比较大,socket 没有有效的重复利用

About

IdleBus 空闲对象管理容器,有效组织对象重复利用,自动创建、销毁,解决【实例】过多且长时间占用的问题。

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 100.0%