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技术请继续关注武汉北大青鸟官网。
Copyright (c) 2006-2020 武汉宏鹏职业培训学校 版权所有 All Rights Reserved.