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

static void Main(string[] args)
{
InstancePoolResolver.Register<OrderQueryServiceInterface, OrderQueryService>(); while (true)
{
Thread.Sleep();
Console.Clear(); for (int i = ; i < ;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(); //故意长时间占用对象
}
}
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() == )
return new InstanceSettingAttribute() { MaxInstanceGlobal=}; return (InstanceSettingAttribute)attrs[];
}
}

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

C# 对象池的实现(能限制最大实例数量,类似于WCF的MaxInstanceCount功能)的更多相关文章

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

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

  2. Apache common pool2 对象池

    对象池的容器:包含一个指定数量的对象.从池中取出一个对象时,它就不存在池中,直到它被放回.在池中的对象有生命周期:创建,验证,销毁,对象池有助于更好地管理可用资源,防止JVM内部大量临时小对象,频繁触 ...

  3. Java之对象池

    单例模式是限制了一个类只能有一个实例,对象池模式则是限制一个类实例的个数.对象池类就像是一个对象管理员,它以Static列表(也就是装对象的池子)的形式存存储某个实例数受限的类的实例,每一个实例还要加 ...

  4. Java对象池

    单例模式是限制了一个类只能有一个实例,对象池模式则是限制一个类实例的个数.对象池类就像是一个对象管理员,它以Static列表(也就是装对象的池子)的形式存存储某个实例数受限的类的实例,每一个实例还要加 ...

  5. Java对象池示例

    单例模式是限制了一个类只能有一个实例,对象池模式则是限制一个类实例的个数.对象池类就像是一个对象管理员,它以Static列表(也就是装对象的池子)的形式存存储某个实例数受限的类的实例,每一个实例还要加 ...

  6. 对象池在 .NET (Core)中的应用[1]: 编程体验

    借助于有效的自动化垃圾回收机制,.NET让开发人员不在关心对象的生命周期,但实际上很多性能问题都来源于GC.并不说.NET的GC有什么问题,而是对象生命周期的跟踪和管理本身是需要成本的,不论交给应用还 ...

  7. 对象池在 .NET (Core)中的应用[2]: 设计篇

    <编程篇>已经涉及到了对象池模型的大部分核心接口和类型.对象池模型其实是很简单的,不过其中有一些为了提升性能而刻意为之的实现细节倒是值得我们关注.总的来说,对象池模型由三个核心对象构成,它 ...

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

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

  9. Egret中的对象池ObjectPool

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

随机推荐

  1. Javascript数组系列一之栈与队列

    所谓数组(英语:Array),是有序的元素序列. 若将有限个类型相同的变量的集合命名,那么这个名称为数组名. 组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量. ---百度百科 ...

  2. 在Windows服务中托管 ASP.NET Core的坑

    按照官网教程 https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/windows-service?view=aspnetcore- ...

  3. Spark SQL整体架构

    0.整体架构 注意:Spark SQL是Spark Core之上的一个模块,所有SQL操作最终都通过Catalyst翻译成类似的Spark程序代码被Spark Core调度执行,其过程也有Job.St ...

  4. Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)

    1 前景回顾 1.1 Linux的调度器组成 2个调度器 可以用两种方法来激活调度 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测 ...

  5. 我在 Mac 上都用什么

    我在 Mac 上都用什么 Homebrew Homebrew 是统一管理 macOS 中应用的最佳方法之一,而且大量优秀的应用都可以在 Homebrew 中找到. 就不做过多介绍了, 有兴趣可以看相关 ...

  6. PHP中判断变量是否存在的方式

    isset()函数判断变量是否设置. thinkPHP中判断select查询时返回值是否为空  $object->isEmpty() empty():当变量存在,并且是一个非空非零的值时,返回 ...

  7. docker往阿里云推镜像和打包镜像

    向仓库推镜像 1. 登录到阿里云docker镜像站点,然后创建仓库. 2.要按照阿里云官方给定的仓库名称来使用,所以我们一般都要继续给准备要上传的镜像二次添加标签,如下所示: 3.在终端登录阿里云站点 ...

  8. 浅析data:image/png;base64的应用

    ...我也是加一个网安交流群发现了他们的入群密码是这个 数据:图像/ PNG; BASE64,iVBORw0KGgoAAAANSUhEUgAAANwAAAAoCAIAAAAaOwPZAAAAAXNSR ...

  9. Spring的AOP基于AspectJ的注解方式开发3

    上上偏博客介绍了@Aspect,@Before 上篇博客介绍了spring的AOP开发的注解通知类型:@Before,@AfterThrowing,@After,@AfterReturning,@Ar ...

  10. docker 中运行 mysql

    在宿主机Host的终端执行: 1. 搜索docker镜像仓库中提供的mysql docker search mysql 2.下载mysql镜像 docker pull mysql 3.改变目录权限,非 ...