C# 对象池的实现

对象池服务可以减少从头创建每个对象的系统开销。在激活对象时,它从池中提取。在停用对象时,它放回池中,等待下一个请求。
我们来看下主线程中,如何与对象池打交道:

static void Main(string[] args)
{
InstancePoolResolver.Register<OrderQueryServiceInterface, OrderQueryService>(); while (true)
{
Thread.Sleep(2000);
Console.Clear(); for (int i = 0; i < 20;i++ )
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ConsumeObject));
}
}
} private static void ConsumeObject(object state)
{
OrderQueryServiceInterface srv = null;
try
{
using (srv = InstancePoolResolver.Resolve<OrderQueryServiceInterface>()) //从对象池中取得对象,没有可用对象则throw exception
{
Console.WriteLine("Object ID--->" + srv.GetHashCode());
Thread.Sleep(1000); //故意长时间占用对象
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
if (srv != null)
srv.Dispose();
}
}

运行效果:

最多只有2个instance,那在哪里设置这个数量呢?请看

是通过Attribute打tag上去的

下面来看看最核心的InstancePoolResolver类

public sealed class InstancePoolResolver
{
private static Dictionary<Type, Type> typeMappers = new Dictionary<Type, Type>();
private static Dictionary<Type, int> typeMappersMaxInstanceCount = new Dictionary<Type, int>();
private static Dictionary<Type, List<PoolableObject>> typeInstances = new Dictionary<Type, List<PoolableObject>>(); private static object o4lock = new object();
public static void Register<T, TProvider>()
where TProvider : class, new()
{
if (typeMappers.ContainsKey(typeof(T)))
throw new Exception("Key existed"); lock (o4lock)
{
Type t = typeof(T);
typeMappers.Add(t, typeof(TProvider));
typeInstances.Add(t, new List<PoolableObject>()); InstanceSettingAttribute setting = GetInstanceSettingAttribute(typeof(TProvider));
typeMappersMaxInstanceCount.Add(t, setting.MaxInstanceGlobal);
}
} public static T Resolve<T>()
where T: PoolableObject
{
Type t = typeof(T);
if (!typeMappers.ContainsKey(t) || !typeInstances.ContainsKey(t))
throw new Exception("Key empty, register please"); lock (o4lock)
{
List<PoolableObject> instances = typeInstances[t];
if (instances == null)
{
instances = new List<PoolableObject>();
typeInstances[t] = instances;
}
foreach (PoolableObject o in instances)//是否已经存在已有闲置对象
{
if (o.IsInPool)
{
o.IsInPool = false;
return (T)o;
}
}
if (instances.Count < typeMappersMaxInstanceCount[t])//new新对象到对象池中
{
Type type = typeMappers[t];
PoolableObject obj = (PoolableObject)Activator.CreateInstance(type);
instances.Add(obj);
obj.IsInPool = false;
return (T)obj;
}
}
throw new Exception("Object Pool fulled!"); //没有多余的资源
} private static InstanceSettingAttribute GetInstanceSettingAttribute(Type type)
{
object[] attrs = type.GetCustomAttributes(typeof(InstanceSettingAttribute), false);
if (attrs == null || attrs.Count() == 0)
return new InstanceSettingAttribute() { MaxInstanceGlobal=10}; return (InstanceSettingAttribute)attrs[0];
}
}

其实很简单,只是多了个获取Attribute的函数

自省推动进步,视野决定未来。
心怀远大理想。
为了家庭幸福而努力。
用A2D科技,服务社会。
 
分类: 架构可扩展

C# 对象池的实现的更多相关文章

  1. 设计模式之美:Object Pool(对象池)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...

  2. Egret中的对象池ObjectPool

    为了可以让对象复用,防止大量重复创建对象,导致资源浪费,使用对象池来管理. 对象池具体含义作用,自行百度. 一 对象池A 二 对象池B 三 字符串key和对象key的效率 一 对象池A /** * 对 ...

  3. 对象池与.net—从一个内存池实现说起

    本来想写篇关于System.Collections.Immutable中提供的ImmutableList里一些实现细节来着,结果一时想不起来源码在哪里--为什么会变成这样呢--第一次有了想写分析的源码 ...

  4. 通用对象池ObjectPool的一种简易设计和实现方案

    对象池,最简单直接的作用当然是通过池来减少创建和销毁对象次数,实现对象的缓存和复用.我们熟知的线程池.数据库连接池.TCP连接池等等都是非常典型的对象池. 一个基本的简易对象池的主要功能实现我认为应该 ...

  5. paip.提升性能----数据库连接池以及线程池以及对象池

    paip.提升性能----数据库连接池以及线程池以及对象池 目录:数据库连接池c3po,线程池ExecutorService:Jakartacommons-pool对象池 作者Attilax  艾龙, ...

  6. common-pool2对象池(连接池)的介绍及使用

    我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...

  7. javascript设计模式学习之四——单例模式,缓存与对象池

    单例模式的定义:确保一个实例,并提供全局访问. 惰性单例的定义:只在需要的时候才创建对象. 在开发中,有些对象往往只需要一个,比如线程池.全局缓存.浏览器中的window对象等. java中的单例 关 ...

  8. Unity3D 基于预设(Prefab)的泛型对象池实现

    背景 在研究Inventory Pro插件的时候,发现老外实现的一个泛型对象池,觉得设计的小巧实用,不敢私藏,特此共享出来. 以前也看过很多博友关于对象池的总结分享,但是世界这么大,这么复杂到底什么样 ...

  9. 深度剖析C++对象池自动回收技术实现

    http://www.tuicool.com/articles/mQBfQfN 对象池可以显著提高性能,如果一个对象的创建非常耗时或非常昂贵,频繁去创建的话会非常低效.对象池通过对象复用的方式来避免重 ...

  10. Apache Commons-pool实现对象池(包括带key对象池)

    Commons-pool是一个apache开源组织下的众多项目的一个.其被广泛地整合到众多需要对象池功能的项目中. 官网:http://commons.apache.org/proper/common ...

随机推荐

  1. C#随机双色球

    using System; using System.Collections.Generic; namespace ConsoleApplicationRandnumber { class Progr ...

  2. iOS 开发者必不可少的 75 个工具

    如果你去到一位熟练的木匠的工作室,你总是能发现他/她有一堆工具来完成不同的任务. 软件开发同样如此.你可以从软件开发者如何使用工具中看出他水准如何.有经验的开发者精于使用工具.对你目前所使用的工具不断 ...

  3. RabbitMQ基本管理(上)

    1.1.2  显示RabbitMQ进程 查看RabbitMQ进程信息,输入以下命令: <span style="font-size:18px;"><strong& ...

  4. 用windows性能监视器监控sqlserver的常见指标

    用windows性能监视器监控sqlserver的常见指标   上边文章中提到win的性能监视器是监控数据库性能必备的工具,接下来我就给大家介绍一些常见的监控指标,其实无非就是磁盘,cpu,内存等硬件 ...

  5. EF结合SqlBulkCopy

    EF结合SqlBulkCopy在项目中的使用 这是我第一次写博客,由于水平有限,写不出什么好东西,还望见谅. 我现在参与的这个项目采用的是EF框架,方便了数据库的访问.但在实际中,发现项目中导入市县E ...

  6. Windows服务之启动、停止、暂停、继续

    原文:Windows服务之启动.停止.暂停.继续 Windows服务之启动.停止.暂停.继续 2011-11-09 15:07:37     我来说两句 收藏    我要投稿    [字体:小 大] ...

  7. JS中实现A*算法寻路

    <html><head><title>use A* to find path...</title></head><body style ...

  8. ExtJS4 便捷三层开发模式

    ExtJS4 便捷三层开发模式 定义类已经不是ext4.x一个新特性,但与ext3.x的自定义类有语法上的区别.将相关模块封装成类可以有效的减少浏览器的压力,提高渲染速度,同时抽象每一个可重用方法,减 ...

  9. SQL点滴10—使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比

    原文:SQL点滴10-使用with语句来写一个稍微复杂sql语句,附加和子查询的性能对比 今天偶尔看到sql中也有with关键字,好歹也写了几年的sql语句,居然第一次接触,无知啊.看了一位博主的文章 ...

  10. 如何用CSC.exe来编译Visual C#的代码文件

    原文:如何用CSC.exe来编译Visual C#的代码文件 C#的编译过程      如何用CSC.exe来编译Visual C#的代码文件   Csc.exe 编译器的位置路径:C:\Window ...