zoukankan      html  css  js  c++  java
  • C# 对象池的实现(能限制最大实例数量,类似于WCF的MaxInstanceCount功能)

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

    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的函数

  • 相关阅读:
    HTML Meta中添加X-UA-Compatible和IE=Edge,chrome=1有什么作用
    CSS+DIV定位分析(relative,absolute,static,fixed)
    Web中常用字体介绍
    CSS中强大的EM
    一线开发忙着实现,二线开发忙着变现
    Eclipse之父、《设计模式》作者、Junit作者之Erich Gamma
    著名软件工程师与作家、极限编程的创始者、JUnit作者之Kent Beck
    学习要构造反馈闭环
    技术人员也要全面发展
    2019第13周日
  • 原文地址:https://www.cnblogs.com/aarond/p/ObjectPool.html
Copyright © 2011-2022 走看看