北大青鸟鲁广校区

北大青鸟鲁广校区

  • 北大青鸟徐东校区
  • 北大青鸟光谷校区
  • 北大青鸟宏鹏IT校区
  • 荆州青鸟之家
  • 襄阳青鸟之家

15902769092

百日千才

.net并行库如何写对象池 北大青鸟.net技术

2013-03-16 08:37来源:武汉北大青鸟鲁广校区作者:武汉宏鹏

北大青鸟武汉宏鹏鲁广校区.net技术是该校主打课程之一,为了让学员学到更多更实用的技术,北大青鸟教员为学子们提供了在线技术指导,官网直接登载相关技术资料,请往下了解。

 ObjectPoolBase类,大家不用去了解TObjectPool, TObjectPoolDomain, TObjectDomain三个泛型参数,改成一个TObject也可以使用。

其构造中的四个参数分别代表:

minSize:池中少个数

maxSize:池中更大个数

growSize:增长/回收个数

maintenanceMilliseconds:维护间隔

运行机制:

在BorrowObject时,如果可以在FREES中取得对象则返回,如果获取失败,则当池中对象个数小于更大个数时,创建对象,否则等待对象返还并重试。

当使用完对象时可通过ReturnObject返还对象,

对象池在指定的maintenanceMilliseconds的间隔内会维护池子的大小,

可重载对象池的OnCreateObject创建对象,OnDestroyObject销毁对象,OnActiveObject激活对象和OnDeactivate使对象进入休眠,

可使用USING语句在跳出代码块是自动返还对象。

using(var po = ObjectPool.GetPoolPoolObject())

{

  po.Object.xxx();

  ....

}

具体代码如下:

public abstract class ObjectPoolBase<TObjectPool, TObjectPoolDomain, TObject, TObjectDomain>
       where TObjectPool : ObjectPoolBase<TObjectPool, TObjectPoolDomain, TObject, TObjectDomain>
       where TObject : class
   {
       static ObjectPoolBase()
       {
           Instance = ContainerManager.Resolve<TObjectPool, TObjectPoolDomain>();
           ObjectPoolManager.Instance.RegisterObjectPool<TObjectPool, TObjectPoolDomain, TObject, TObjectDomain>(Instance);
       }

       public static TObjectPool Instance
       {
           get;
           private set;
       }

       public static IPoolObject<TObject> GetPoolObject()
       {
           return new InternalPoolObject();
       }

       private ConcurrentBag<TObject> frees;
       private ConcurrentDictionary<TObject, byte> borrowed;
       private long count;
       private int minSize;
       private int growSize;
       private int maxSize;
       private long maintenanceMilliseconds;
       private Timer maintenanceTimer;
       private AutoResetEvent are;
       private volatile bool exit;

       protected ObjectPoolBase(int minSize, int growSize, int maintenanceMillseconds)
           : this(minSize, int.MaxValue, growSize, maintenanceMillseconds)
       {

       }

       public ObjectPoolBase(int minSize, int maxSize, int growSize, int maintenanceMillseconds)
       {
           CheckUtility.ArgumentPositiveNumber(minSize, "minSize");
           CheckUtility.ArgumentPositiveNumber(growSize, "growSize");
           CheckUtility.ArgumentPositiveNumber(maintenanceMillseconds, "maintenanceMillseconds");
           CheckUtility.ArgumentGreaterThanArgument(minSize, "minSize", maxSize, "maxSize");

           this.minSize = minSize;
           this.growSize = growSize;
           this.maxSize = maxSize;
           this.maintenanceMilliseconds = maintenanceMillseconds;
           this.frees = new ConcurrentBag<TObject>();
           this.borrowed = new ConcurrentDictionary<TObject, byte>();
           this.count = 0;
           this.are = new AutoResetEvent(false);
           this.exit = false;
           this.maintenanceTimer = new Timer(this.TaskMaintenance, null, this.maintenanceMilliseconds, Timeout.Infinite);
       }

       public void Shutdown()
       {
           if (this.exit)
           {
               return;
           }

           this.exit = true;
           this.are.WaitOne();
       }

       private bool ShutdownIfExit()
       {
           if (this.exit)
           {
               this.are.Set();
           }

           return this.exit;
       }

       private void WriteToLog(string messageFormat, params object[] args)
       {
           string message = CheckUtility.ArrayIsNullOrEmpty(args) ? messageFormat : string.Format(messageFormat, args);
           LoggingWriter.WriteFormat("[{0}] {1} {2}", this.PoolName, message, this);
       }

       private void TaskMaintenance(object state)
       {
           this.WriteToLog("Trigger Maintenance");

           if (this.ShutdownIfExit())
           {
               return;
           }

           Task.Factory.StartNew(() =>
           {
               if (this.ShutdownIfExit())
               {
                   return;
               }

               this.WriteToLog("Begin Maintenance");

               if (Interlocked.Read(ref this.count) <= this.maxSize)
               {
                   lock (this)
                   {
                       if (Interlocked.Read(ref this.count) <= this.maxSize)
                       {
                           if (this.frees.Count > this.minSize)
                           {
                               this.MaintenanceDestroy(Math.Min(this.growSize, Math.Abs(this.frees.Count - this.minSize)));
                           }
                           else if (this.frees.Count < this.minSize)
                           {
                               this.MaintenanceCreate(Math.Min(this.growSize, Math.Abs(this.frees.Count - this.minSize)));
                           }
                       }
                   }
               }

               this.WriteToLog("After Maintenance");

               if (this.ShutdownIfExit())
               {
                   return;
               }

               this.maintenanceTimer.Change(this.maintenanceMilliseconds, Timeout.Infinite);

           }, TaskCreationOptions.LongRunning);
       }

       public TObject BorrowObject()
       {
           this.WriteToLog("Before Borrow");

           TObject t;

           do
           {
               if (!this.frees.TryTake(out t))
               {
                   lock (this)
                   {
                       while (!this.frees.TryTake(out t))
                       {
                           if (this.exit)
                           {
                               throw new ObjectDisposedException(this.GetType().FullName);
                           }

                           long count = Interlocked.Read(ref this.count);

                           if (Interlocked.Read(ref this.count) >= this.maxSize)
                           {
                               Monitor.Wait(this, 10000);
                               continue;
                           }
                           else
                           {
                               long growSize = Math.Min(this.growSize, Math.Abs(this.count + this.growSize - this.maxSize));

                               if (growSize <= 0)
                               {
                                   Monitor.Wait(this, 10000);
                                   continue;
                               }
                               else
                               {
                                   this.MaintenanceCreate(growSize);
                               }
                           }
                       }
                   }
               }

           } while (!this.ActiveObject(t));

           this.borrowed.TryAdd(t, 0);
           this.OnBorrow(t);

           this.WriteToLog("AfterBorrow");

           return t;
       }

       protected virtual void OnBorrow(TObject obj)
       {

       }

       public void ReturnObject(TObject obj)
       {
           "obj".NullArgument(obj);

           this.WriteToLog("Before Return");

           byte b;

           if (!this.borrowed.TryRemove(obj, out b))
           {
               throw new InvalidOperationException(SR.InvalidObjectForPool);
           }

           if (this.DeactiveObject(obj))
           {
               this.frees.Add(obj);
           }
           else
           {
               Interlocked.Decrement(ref this.count);
           }

           this.WriteToLog("After Return");
       }

       protected void MaintenanceCreate(long size)
       {
           this.WriteToLog("Before Maintenance Create size: {0}", size);

           Parallel.For(0, size, (i) =>
           {
               if (this.exit)
               {
                   return;
               }

               if (Interlocked.Read(ref this.count) < this.maxSize)
               {
                   TObject t;

                   if (this.CreateObject(out t))
                   {
                       this.frees.Add(t);
                       Interlocked.Increment(ref this.count);
                   }
               }
           });

           this.WriteToLog("After Maintenance Create");
       }

       protected void MaintenanceDestroy(long size)
       {
           this.WriteToLog("Before Maintenance Destroy size: {0}", size);

           Parallel.For(0, size, (i) =>
           {
               if (this.exit)
               {
                   return;
               }

               TObject t;

               if (this.frees.TryTake(out t))
               {
                   this.DestroyObject(t);
                   Interlocked.Decrement(ref this.count);
               }
           });

           this.WriteToLog("After Maintenance Destroy");
       }

       private bool CreateObject(out TObject t)
       {
           this.WriteToLog("Create Object");

           t = default(TObject);

           try
           {
               t = this.OnCreateObject();

               if (null == t)
               {
                   throw new NullReferenceException(SR.CreatedNullObjectForPool);
               }

               this.WriteToLog("Object Created");
               return true;
           }
           catch (Exception e)
           {
               LoggingWriter.WriteLog(e);
               return false;
           }
       }

       protected virtual TObject OnCreateObject()
       {
           return ContainerManager.Resolve<TObject, TObjectDomain>();
       }

       private bool ActiveObject(TObject t)
       {
           this.WriteToLog("Active Object");

           try
           {
               this.OnActiveObject(t);
               return true;
           }
           catch (Exception e)
           {
               LoggingWriter.WriteLog(e);
               this.DestroyObject(t);
               return false;
           }
       }

       protected virtual void OnActiveObject(TObject obj)
       {

       }

       private bool DeactiveObject(TObject t)
       {
           this.WriteToLog("Deactive Object");

           try
           {
               this.OnDeactivateObject(t);
               return true;
           }
           catch (Exception e)
           {
               LoggingWriter.WriteLog(e);
               this.DestroyObject(t);
               return false;
           }
       }

       protected virtual void OnDeactivateObject(TObject obj)
       {

       }

       private void DestroyObject(TObject t)
       {
           this.WriteToLog("Destroy Object");

           try
           {
               byte b;

               if (this.borrowed.TryRemove(t, out b))
               {
                   Interlocked.Decrement(ref this.count);
                   this.OnDestroyObject(ref t);
               }
           }
           catch (Exception e)
           {
               LoggingWriter.WriteLog(e);
           }
       }

       protected virtual void OnDestroyObject(ref TObject obj)
       {
           IDisposable disposable = obj as IDisposable;

           if (null != disposable)
           {
               try
               {
                   disposable.Dispose();
               }
               catch (Exception e)
               {
                   LoggingWriter.WriteLog(e);
               }
           }
           else
           {
               obj = null;
           }
       }

       public virtual string PoolName
       {
           get
           {
               return typeof(TObjectPool).Name;
           }
       }

       public override string ToString()
       {
           return string.Format("[Pool Info] count: {0},  frees {1}, borrowed {2}, minSize {3}, maxSize {4} growSize {5}",
                                               Interlocked.Read(ref this.count),
                                               this.frees.Count,
                                               this.borrowed.Count,
                                               this.minSize,
                                               this.maxSize,
                                               this.growSize);
       }

       private class InternalPoolObject : IPoolObject<TObject>, IDisposable
       {
           private TObject obj;

           public InternalPoolObject()
           {
               this.obj = null;
           }

           public TObject Object
           {
               get
               {
                   if (null == this.obj)
                   {
                       this.obj = Instance.BorrowObject();
                   }

                   return this.obj;
               }
           }

           public void Dispose()
           {
               if (null != this.obj)
               {
                   Instance.ReturnObject(this.obj);
               }
           }
       }
   }

      同学们看明白了吗?想了解更多.net技术请继续关注武汉北大青鸟官网。

关闭

只为了方便您就学 北大青鸟鲁广校区 北大青鸟鲁广校区

武汉市洪山区珞喻路724号(地铁二号线光谷广场站F口出)

全真项目实战 入学签就业协议

Copyright (c) 2006-2020 武汉宏鹏职业培训学校 版权所有 All Rights Reserved.