zoukankan      html  css  js  c++  java
  • [转]ObjectPool

    ObjectPool
    //#define DISABLE_POOL
    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace ObjectPool {
    public interface IObjectPoolMethods : IDisposable {
    /// <summary>
    /// This method is used to setup an instance of
    /// an object.
    /// </summary>
    /// <remarks>
    /// Use an empty constructor in the class and
    /// entirely rely on this method to setup and
    /// initialize the object if the class is going
    /// to be used for object pooling. Do not call this
    /// method from the constructor or it will be called
    /// twice and will affect performace.
    /// </remarks>
    /// <param name="setupParameters"></param>
    void SetupObject(params object[] setupParameters);
    /// <summary>
    /// This event must be fired when dispose is called
    /// or the Object Pool will not be able to work
    /// </summary>
    event EventHandler Disposing;
    }

    /// <summary>
    /// A generic class that provide object pooling functionality
    /// to classes that implement the IObjectPoolMethods interface
    /// </summary>
    /// <remarks>
    /// As long as the lock(this) statements remain this class is thread
    /// </remarks>
    /// <typeparam name="T">
    /// The type of the object that should be pooled
    /// </typeparam>
    public class ObjectPool<T> where T : IObjectPoolMethods, new() {
    /// <summary>
    /// The MAX_POOL does not restrict the maximum
    /// number of objects in the object pool
    /// instead it restricts the number of
    /// disposed objects that the pool will maintain
    /// a reference too and attempt to pool. This
    /// number should be set based on a memory and
    /// usage anaylsis based on the types of objects
    /// being pooled. I have found the best results
    /// by setting this number to average peak objects
    /// in use at one time.
    /// </summary>
    /// <value>100</value>
    private const int MAX_POOL = 2000;
    /// <summary>
    /// The static instance of the object pool. Thankfully the
    /// use of generics eliminates the need for a hash for each
    /// different pool type
    /// </summary>
    private static ObjectPool<T> me = new ObjectPool<T>();
    /// <summary>
    /// Using a member for the max pool count allows different
    /// types to have a different value based on usage analysis
    /// </summary>
    private int mMaxPool = ObjectPool<T>.MAX_POOL;
    /// <summary>
    /// A Linked List of the WeakReferences to the objects in the pool
    /// When the count of the list goes beyond the max pool count
    /// items are removed from the end of the list. The objects at the
    /// end of the list are also most likely to have already been collected
    /// by the garbage collector.
    /// </summary>
    private LinkedList<WeakReference> objectPool = new LinkedList<WeakReference>();
    /// <summary>
    /// Return the singleton instance
    /// </summary>
    /// <returns>
    /// The single instance allowed for the given type
    /// </returns>
    public static ObjectPool<T> GetInstance() {
    return me;
    }
    /// <summary>
    /// This method gets called on the object disposing
    /// event for objects created from this object pool class.
    /// If the implementing class does not fire this event on
    /// dispose the object pooling will not work
    /// </summary>
    /// <param name="sender">
    /// The class instance that is pooled
    /// </param>
    /// <param name="e">
    /// An empty event args parameters
    /// </param>
    /// <exception cref="System.ArgumentException">
    /// Thrown if the type of the object in the weak reference does not match
    /// the type of this generic instance
    /// </exception>
    private void Object_Disposing(object sender, EventArgs e) {
    //The lock is required here because this method may
    //be called from events on different threads
    lock (this) {
    Add(
    new WeakReference(sender));
    }
    }
    /// <summary>
    /// This method will add a new instance to be tracked by
    /// this object pooling class. This should be a reference
    /// to an object that was just disposed otherwise it makes no
    /// sense and will likely cause some serious problems.
    /// </summary>
    /// <param name="weak">
    /// WeakReference to the object that was disposed
    /// </param>
    /// <exception cref="System.ArgumentException">
    /// Thrown if the type of the object in the weak reference does not match
    /// the type of this generic instance
    /// </exception>
    private void Add(WeakReference weak) {
    objectPool.AddFirst(weak);
    if (objectPool.Count >= mMaxPool) {
    objectPool.RemoveLast();
    }
    }
    /// <summary>
    /// Remove the reference from the pool. This should
    /// only be called when the object in the pool
    /// is being reactivated or if the weak reference has
    /// been determined to be expired.
    /// </summary>
    /// <param name="weak">
    /// A reference to remove
    /// </param>
    /// <exception cref="System.ArgumentException">
    /// Thrown if the type of the object in the weak reference does not match
    /// the type of this generic instance
    /// </exception>
    private void Remove(WeakReference weak) {
    objectPool.Remove(weak);
    }
    ///<summary>
    /// This method will verify that the type of the weak
    /// reference is valid for this generic instance. I haven't
    /// figured out a way do it automagically yet
    /// </summary>
    /// <exception cref="System.ArgumentException">
    /// Thrown if the type of the object in the weak reference does not match
    /// the type of this generic instance
    /// </exception>
    private void TypeCheck(WeakReference weak) {
    if (weak.Target != null && weak.Target.GetType() != typeof(T)) {
    throw new ArgumentException("Target type does not match pool type", "weak");
    }
    }

    /// <summary>
    /// This method will return an object reference that is fully
    /// setup. It will either retrieve the object from the object
    /// pool if there is a disposed object available or it will
    /// create a new instance.
    /// </summary>
    /// <param name="setupParameters">
    /// The setup parameters required for the
    /// IObjectPoolMethods.SetupObject method. Need to find a
    /// way to check for all of the types efficiently and at
    /// compile time.
    /// </param>
    /// <returns>
    /// The reference to the object
    /// </returns>
    public T GetObjectFromPool(params object[] setupParameters) {
    T result
    = default(T);
    #if DISABLE_POOL
    result
    = new T();
    result.SetupObject(setupParameters);
    return result;
    #else
    lock (this) {
    WeakReference remove
    = null;
    foreach (WeakReference weak in objectPool) {
    object o = weak.Target;
    if (o != null) {
    remove
    = weak;
    result
    = (T)o;
    GC.ReRegisterForFinalize(result);
    break;
    }
    }
    if (remove != null) {
    objectPool.Remove(remove);
    }
    }
    if (result == null) {
    result
    = new T();
    result.Disposing
    += new EventHandler(Object_Disposing);
    }
    result.SetupObject(setupParameters);
    return result;
    #endif
    }


    }
    }
    SampleObject
  • 相关阅读:
    HDU 2116 Has the sum exceeded
    HDU 1233 还是畅通工程
    HDU 1234 开门人和关门人
    HDU 1283 最简单的计算机
    HDU 2552 三足鼎立
    HDU 1202 The calculation of GPA
    HDU 1248 寒冰王座
    HDU 1863 畅通工程
    HDU 1879 继续畅通工程
    颜色对话框CColorDialog,字体对话框CFontDialog使用实例
  • 原文地址:https://www.cnblogs.com/Googler/p/1754572.html
Copyright © 2011-2022 走看看