123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Data;
- using System.Data.SqlClient;
- using System.Data.Common;
- using System.Threading;
- using System.Collections;
- namespace DateBaseConnectionPool
- {
- /// <summary>
- /// 数据库连接池,默认数据库连接方案是ODBC
- /// </summary>
- public class Pool : IDisposable
- {
- #region 变量定义
- //属性
- private int _realFormPool;//连接池中存在的实际连接数(包含失效的连接)
- private int _potentRealFormPool;//连接池中存在的实际连接数(有效的实际连接)
- private int _spareRealFormPool;//空闲的实际连接
- private int _useRealFormPool;//已分配的实际连接
- private int _readOnlyFormPool;//连接池已经分配多少只读连接
- private int _useFormPool;//已经分配出去的连接数
- private int _spareFormPool;//目前可以提供的连接数
- private int _maxConnection;//最大连接数,最大可以创建的连接数目
- private int _minConnection;//最小连接数
- private int _seepConnection;//每次创建连接的连接数
- private int _keepRealConnection;//保留的实际空闲连接,以攻可能出现的ReadOnly使用,当空闲连接不足该数值时,连接池将创建seepConnection个连接
- private int _exist = 20;//每个连接生存期限 20分钟
- private int _maxRepeatDegree = 5;//可以被重复使用次数(引用记数),当连接被重复分配该值所表示的次数时,该连接将不能被分配出去
- //当连接池的连接被分配尽时,连接池会在已经分配出去的连接中,重复分配连接(引用记数)。来缓解连接池压力
- private DateTime _startTime;//服务启动时间
- private string _connString = null;//连接字符串
- private ConnTypeEnum _connType;//连接池连接类型
- private PoolState _ps;//连接池状态
- //内部对象
- private List<ConnStruct> al_All = new List<ConnStruct>();//实际连接
- private Hashtable hs_UseConn = new Hashtable();//正在使用的连接
- private System.Timers.Timer time;//监视器记时器
- private Thread threadCreate;//创建线程
- private bool isThreadCheckRun = false;
- //private Mutex mUnique = new Mutex();
- #endregion
- //--------------------------------------------------------------------
- #region 构造方法 与 初始化函数
- /// <summary>
- /// 初始化连接池
- /// </summary>
- /// <param name="connectionString">数据库连接字符串</param>
- public Pool(string connectionString)
- { InitConnectionPool(connectionString, ConnTypeEnum.Odbc, 200, 30, 10, 5, 5); }
- /// <summary>
- /// 初始化连接池
- /// </summary>
- /// <param name="connectionString">数据库连接字符串</param>
- /// <param name="cte">数据库连接类型</param>
- public Pool(string connectionString, ConnTypeEnum cte)
- { InitConnectionPool(connectionString, cte, 200, 30, 10, 5, 5); }
- /// <summary>
- /// 初始化连接池
- /// </summary>
- /// <param name="connectionString">数据库连接字符串</param>
- /// <param name="cte">数据库连接类型</param>
- /// <param name="maxConnection">最大连接数,最大可以创建的连接数目</param>
- /// <param name="minConnection">最小连接数</param>
- public Pool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection)
- { InitConnectionPool(connectionString, cte, maxConnection, minConnection, 10, 5, 5); }
- /// <summary>
- /// 初始化连接池
- /// </summary>
- /// <param name="connectionString">数据库连接字符串</param>
- /// <param name="cte">数据库连接类型</param>
- /// <param name="maxConnection">最大连接数,最大可以创建的连接数目</param>
- /// <param name="minConnection">最小连接数</param>
- /// <param name="seepConnection">每次创建连接的连接数</param>
- /// <param name="keepConnection">保留连接数,当空闲连接不足该数值时,连接池将创建seepConnection个连接</param>
- public Pool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection)
- { InitConnectionPool(connectionString, cte, maxConnection, minConnection, seepConnection, keepConnection, 5); }
- /// <summary>
- /// 初始化连接池
- /// </summary>
- /// <param name="connectionString">数据库连接字符串</param>
- /// <param name="cte">数据库连接类型</param>
- /// <param name="maxConnection">最大连接数,最大可以创建的连接数目</param>
- /// <param name="minConnection">最小连接数</param>
- /// <param name="seepConnection">每次创建连接的连接数</param>
- /// <param name="keepConnection">保留连接数,当空闲连接不足该数值时,连接池将创建seepConnection个连接</param>
- /// <param name="keepRealConnection">当空闲的实际连接不足该值时创建连接,直到达到最大连接数</param>
- public Pool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection, int keepRealConnection)
- { InitConnectionPool(connectionString, cte, maxConnection, minConnection, seepConnection, keepConnection, keepRealConnection); }
- /// <summary>
- /// 初始化函数
- /// </summary>
- protected void InitConnectionPool(string connectionString, ConnTypeEnum cte, int maxConnection, int minConnection, int seepConnection, int keepConnection, int keepRealConnection)
- {
- if (cte == ConnTypeEnum.None)
- throw new ConnTypeExecption();//参数不能是None
- _ps = PoolState.UnInitialize;
- this._connString = connectionString;
- this._connType = cte;
- this._minConnection = minConnection;
- this._seepConnection = seepConnection;
- this._keepRealConnection = keepRealConnection;
- this._maxConnection = maxConnection;
- this.time = new System.Timers.Timer(500);
- this.time.Stop();
- this.time.Elapsed += new System.Timers.ElapsedEventHandler(time_Elapsed);
- this.threadCreate = new Thread(new ThreadStart(createThreadProcess));
- }
- #endregion
- //--------------------------------------------------------------------
- #region 属性部分
- /// <summary>
- /// 连接池服务状态
- /// </summary>
- public PoolState State
- { get { return _ps; } }
- /// <summary>
- /// 连接池是否启动,改变该属性将相当于调用StartServices或StopServices方法,注:只有连接池处于Run,Stop状态情况下才可以对此属性赋值
- /// </summary>
- public bool Enable
- {
- get
- {
- if (_ps == PoolState.Run)
- return true;
- else
- return false;
- }
- set
- {
- if (_ps == PoolState.Run || _ps == PoolState.Stop)
- if (value == true)
- StartServices();
- else
- StopServices();
- else
- throw new SetValueExecption();//只有连接池处于Run,Stop状态情况下才可以对此属性赋值
- }
- }
- /// <summary>
- /// 得到或设置连接类型
- /// </summary>
- public ConnTypeEnum ConnectionType
- {
- get { return _connType; }
- set
- {
- if (_ps == PoolState.Stop)
- _connType = value;
- else
- throw new SetValueExecption();//只有在Stop状态时才可操作
- }
- }
- /// <summary>
- /// 连接池使用的连接字符串
- /// </summary>
- public string ConnectionString
- {
- get { return _connString; }
- set
- {
- if (_ps == PoolState.Stop)
- _connString = value;
- else
- throw new SetValueExecption();//只有在Stop状态时才可操作
- }
- }
- /// <summary>
- /// 得到服务器运行时间
- /// </summary>
- public DateTime RunTime
- {
- get
- {
- if (_ps == PoolState.Stop)
- return new DateTime(DateTime.Now.Ticks - _startTime.Ticks);
- else
- return new DateTime(0);
- }
- }
- /// <summary>
- /// 最小连接数
- /// </summary>
- public int MinConnection
- {
- get { return _minConnection; }
- set
- {
- if (value < _maxConnection && value > 0 && value >= _keepRealConnection)
- _minConnection = value;
- else
- throw new ParameterBoundExecption();//参数范围应该在 0~MaxConnection之间,并且应该大于KeepConnection
- }
- }
- /// <summary>
- /// 最大连接数,最大可以创建的连接数目
- /// </summary>
- public int MaxConnection
- {
- get { return _maxConnection; }
- set
- {
- if (value >= _minConnection && value > 0)
- _maxConnection = value;
- else
- throw new ParameterBoundExecption();//参数范围错误,参数应该大于minConnection
- }
- }
- /// <summary>
- /// 每次创建连接的连接数
- /// </summary>
- public int SeepConnection
- {
- get { return _seepConnection; }
- set
- {
- if (value > 0 && value < _maxConnection)
- _seepConnection = value;
- else
- throw new ParameterBoundExecption();//创建连接的步长应大于0,同时小于MaxConnection
- }
- }
- /// <summary>
- /// 保留的实际空闲连接,以攻可能出现的ReadOnly使用
- /// </summary>
- public int KeepRealConnection
- {
- get { return _keepRealConnection; }
- set
- {
- if (value >= 0 && value < _maxConnection)
- _keepRealConnection = value;
- else
- throw new ParameterBoundExecption();//保留连接数应大于等于0,同时小于MaxConnection
- }
- }
- /// <summary>
- /// 自动清理连接池的时间间隔
- /// </summary>
- public double Interval
- {
- get { return time.Interval; }
- set { time.Interval = value; }
- }
- /// <summary>
- /// 每个连接生存期限(单位分钟),默认20分钟
- /// </summary>
- public int Exist
- {
- get { return _exist; }
- set
- {
- if (_ps == PoolState.Stop)
- _exist = value;
- else
- throw new PoolNotStopException();//只有在Stop状态下才可以操作
- }
- }
- /// <summary>
- /// 可以被重复使用次数(引用记数)当连接被重复分配该值所表示的次数时,该连接将不能被分配出去。
- /// 当连接池的连接被分配尽时,连接池会在已经分配出去的连接中,重复分配连接(引用记数)。来缓解连接池压力
- /// </summary>
- public int MaxRepeatDegree
- {
- get { return _maxRepeatDegree; }
- set
- {
- if (value >= 0)
- _maxRepeatDegree = value;
- else
- throw new ParameterBoundExecption();//重复引用次数应大于等于0
- }
- }
- /// <summary>
- /// 连接池最多可以提供多少个连接
- /// </summary>
- public int MaxConnectionFormPool
- { get { return _maxConnection * _maxRepeatDegree; } }
- /// <summary>
- /// 连接池中存在的实际连接数(有效的实际连接)
- /// </summary>
- public int PotentRealFormPool
- {
- get
- {
- if (_ps == PoolState.Run)
- return _potentRealFormPool;
- else
- throw new PoolNotRunException();//连接池处在非运行中
- }
- }
- /// <summary>
- /// 连接池中存在的实际连接数(包含失效的连接)
- /// </summary>
- public int RealFormPool
- {
- get
- {
- if (_ps == PoolState.Run)
- return _realFormPool;
- else
- throw new PoolNotRunException();//连接池处在非运行中
- }
- }
- /// <summary>
- /// 空闲的实际连接
- /// </summary>
- public int SpareRealFormPool
- {
- get
- {
- if (_ps == PoolState.Run)
- return _spareRealFormPool;
- else
- throw new PoolNotRunException();//连接池处在非运行中
- }
- }
- /// <summary>
- /// 已分配的实际连接
- /// </summary>
- public int UseRealFormPool
- {
- get
- {
- if (_ps == PoolState.Run)
- return _useRealFormPool;
- else
- throw new PoolNotRunException();//连接池处在非运行中
- }
- }
- /// <summary>
- /// 连接池已经分配多少只读连接
- /// </summary>
- public int ReadOnlyFormPool
- {
- get
- {
- if (_ps == PoolState.Run)
- return _readOnlyFormPool;
- else
- throw new PoolNotRunException();//连接池处在非运行中
- }
- }
- /// <summary>
- /// 已经分配的连接数
- /// </summary>
- public int UseFormPool
- {
- get
- {
- if (_ps == PoolState.Run)
- return _useFormPool;
- else
- throw new PoolNotRunException();//连接池处在非运行中
- }
- }
- /// <summary>
- /// 目前可以提供的连接数
- /// </summary>
- public int SpareFormPool
- {
- get
- {
- if (_ps == PoolState.Run)
- return _spareFormPool;
- else
- throw new PoolNotRunException();//连接池处在非运行中
- }
- }
- #endregion
- //--------------------------------------------------------------------
- #region 启动服务 与 终止服务
- /// <summary>
- /// 启动服务,线程安全,同步调用
- /// </summary>
- public void StartServices()
- { StartServices(false); }
- /// <summary>
- /// 启动服务,线程安全
- /// </summary>
- /// <param name="ansy">是否异步调用True为是,异步调用指,用户调用该方法后,无须等待创建结束就可继续做其他操作</param>
- public void StartServices(bool ansy)
- {
- lock (this)
- {
- createThreadMode = 0;//工作模式0
- createThreadProcessRun = true;
- createThreadProcessTemp = _minConnection;
- if (_ps == PoolState.UnInitialize)
- threadCreate.Start();
- else if (_ps == PoolState.Stop)
- threadCreate.Interrupt();
- else
- throw new PoolNotStopException();//服务已经运行或者未完全结束
- time.Start();
- }
- if (!ansy)
- while (threadCreate.ThreadState != ThreadState.WaitSleepJoin) { Thread.Sleep(50); }//等待可能存在的创建线程结束
- }
- /// <summary>
- /// 停止服务,线程安全
- /// </summary>
- public void StopServices()
- { StopServices(false); }
- /// <summary>
- /// 停止服务,线程安全
- /// <param name="needs">是否必须退出;如果指定为false与StartServices()功能相同,如果指定为true。将未收回的连接资源关闭,这将是危险的。认为可能你的程序正在使用此资源。</param>
- /// </summary>
- public void StopServices(bool needs)
- {
- lock (this)
- {
- if (_ps == PoolState.Run)
- {
- lock (hs_UseConn)
- {
- if (needs == true)//必须退出
- hs_UseConn.Clear();
- else
- if (hs_UseConn.Count != 0)
- throw new ResCallBackException();//连接池资源未全部回收
- }
- time.Stop();
- while (isThreadCheckRun) { Thread.Sleep(50); }//等待timer事件结束
- createThreadProcessRun = false;
- while (threadCreate.ThreadState != ThreadState.WaitSleepJoin) { Thread.Sleep(50); }//等待可能存在的创建线程结束
- lock (al_All)
- {
- for (int i = 0; i < al_All.Count; i++)
- al_All[i].Dispose();
- al_All.Clear();
- }
- _ps = PoolState.Stop;
- }
- else
- throw new PoolNotRunException();//服务未启动
- }
- UpdateAttribute();//更新属性
- }
- public void Dispose()
- {
- try
- {
- this.StopServices();
- threadCreate.Abort();
- }
- catch (Exception e) { }
- }
- #endregion
- //--------------------------------------------------------------------
- #region 获得连接 与 释放连接
- /// <summary>
- /// 在连接池中申请一个连接,使用None级别,线程安全
- /// </summary>
- /// <param name="gui">发起者</param>
- /// <returns>返回申请到的连接</returns>
- public DbConnection GetConnectionFormPool(object key)
- { return GetConnectionFormPool(key, ConnLevel.None); }
- /// <summary>
- /// 在连接池中申请一个连接,线程安全
- /// </summary>
- /// <param name="key">申请者</param>
- /// <param name="cl">申请的连接级别</param>
- /// <returns>返回申请到的连接</returns>
- public DbConnection GetConnectionFormPool(object key, ConnLevel cl)
- {
- lock (this)
- {
- if (_ps != PoolState.Run)
- throw new StateException();//服务状态错误
- if (hs_UseConn.Count == MaxConnectionFormPool)
- throw new PoolFullException();//连接池已经饱和,不能提供连接
- if (hs_UseConn.ContainsKey(key))
- throw new KeyExecption();//一个key对象只能申请一个连接
- if (cl == ConnLevel.ReadOnly)
- return GetConnectionFormPool_ReadOnly(key);//ReadOnly级别
- else if (cl == ConnLevel.High)
- return GetConnectionFormPool_High(key);//High级别
- else if (cl == ConnLevel.None)
- return GetConnectionFormPool_None(key);//None级别
- else
- return GetConnectionFormPool_Bottom(key);//Bottom级别
- }
- }
- /// <summary>
- /// 申请一个连接资源,只读方式,线程安全
- /// </summary>
- /// <param name="key">申请者</param>
- /// <returns>申请到的连接对象</returns>
- protected DbConnection GetConnectionFormPool_ReadOnly(object key)
- {
- ConnStruct cs = null;
- for (int i = 0; i < al_All.Count; i++)
- {
- cs = al_All[i];
- if (cs.Enable == false || cs.Allot == false || cs.UseDegree == _maxRepeatDegree || cs.IsUse == true)
- continue;
- return GetConnectionFormPool_Return(key, cs, ConnLevel.ReadOnly); //返回得到的连接
- }
- return GetConnectionFormPool_Return(key, null, ConnLevel.ReadOnly);
- }
- /// <summary>
- /// 申请一个连接资源,优先级-高,线程安全
- /// </summary>
- /// <param name="key">申请者</param>
- /// <returns>申请到的连接对象</returns>
- protected DbConnection GetConnectionFormPool_High(object key)
- {
- ConnStruct cs = null;
- ConnStruct csTemp = null;
- for (int i = 0; i < al_All.Count; i++)
- {
- csTemp = al_All[i];
- if (csTemp.Enable == false || csTemp.Allot == false || csTemp.UseDegree == _maxRepeatDegree)//不可以分配跳出本次循环。
- {
- csTemp = null;
- continue;
- }
- if (csTemp.UseDegree == 0)//得到最合适的
- {
- cs = csTemp;
- break;
- }
- else//不是最合适的放置到最佳选择中
- {
- if (cs != null)
- {
- if (csTemp.UseDegree < cs.UseDegree)
- //与上一个最佳选择选出一个最佳的放置到cs中
- cs = csTemp;
- }
- else
- cs = csTemp;
- }
- }
- return GetConnectionFormPool_Return(key, cs, ConnLevel.High);//返回最合适的连接
- }
- /// <summary>
- /// 申请一个连接资源,优先级-中,线程安全
- /// </summary>
- /// <param name="key">申请者</param>
- /// <returns>申请到的连接对象</returns>
- protected DbConnection GetConnectionFormPool_None(object key)
- {
- List<ConnStruct> al = new List<ConnStruct>();
- ConnStruct cs = null;
- for (int i = 0; i < al_All.Count; i++)
- {
- cs = al_All[i];
- if (cs.Enable == false || cs.Allot == false || cs.UseDegree == _maxRepeatDegree)//不可以分配跳出本次循环。
- continue;
- if (cs.Allot == true)
- al.Add(cs);
- }
- if (al.Count == 0)
- return GetConnectionFormPool_Return(key, null, ConnLevel.None);//发出异常
- else
- return GetConnectionFormPool_Return(key, (al[al.Count / 2]), ConnLevel.None);//返回连接
- }
- /// <summary>
- /// 申请一个连接资源,优先级-低,线程安全
- /// </summary>
- /// <param name="key">申请者</param>
- /// <returns>申请到的连接对象</returns>
- protected DbConnection GetConnectionFormPool_Bottom(object key)
- {
- ConnStruct cs = null;
- ConnStruct csTemp = null;
- for (int i = 0; i < al_All.Count; i++)
- {
- csTemp = al_All[i];
- if (csTemp.Enable == false || csTemp.Allot == false || csTemp.UseDegree == _maxRepeatDegree)//不可以分配跳出本次循环。
- {
- csTemp = null;
- continue;
- }
- else//不是最合适的放置到最佳选择中
- {
- if (cs != null)
- {
- if (csTemp.UseDegree > cs.UseDegree)
- //与上一个最佳选择选出一个最佳的放置到cs中
- cs = csTemp;
- }
- else
- cs = csTemp;
- }
- }
- return GetConnectionFormPool_Return(key, cs, ConnLevel.Bottom);//返回最合适的连接
- }
- /// <summary>
- /// 返回DbConnection对象,同时做获得连接时的必要操作
- /// </summary>
- /// <param name="key">key</param>
- /// <param name="cs">ConnStruct对象</param>
- /// <param name="cl">级别</param>
- /// <param name="readOnly">是否为只读属性</param>
- /// <returns></returns>
- private DbConnection GetConnectionFormPool_Return(object key, ConnStruct cs, ConnLevel cl)
- {
- try
- {
- if (cs == null)
- throw new Exception();
- cs.Repeat();
- hs_UseConn.Add(key, cs);
- if (cl == ConnLevel.ReadOnly)
- {
- cs.Allot = false;
- cs.IsRepeat = false;
- }
- }
- catch (Exception e)
- {
- throw new OccasionExecption();//连接资源耗尽,或错误的访问时机。
- }
- finally
- {
- UpdateAttribute();//更新属性
- }
- return cs.Connection;
- }
- /// <summary>
- /// 释放申请的数据库连接对象,线程安全
- /// <param name="key">key表示数据库连接申请者</param>
- /// </summary>
- public void DisposeConnection(object key)
- {
- lock (hs_UseConn)
- {
- ConnStruct cs = null;
- if (_ps == PoolState.Run)
- {
- if (!hs_UseConn.ContainsKey(key))
- throw new NotKeyExecption();//无法释放,不存在的key
- cs = (ConnStruct)hs_UseConn[key];
- cs.IsRepeat = true;
- if (cs.Allot == false)
- if (cs.Enable == true)
- cs.Allot = true;
- cs.Remove();
- hs_UseConn.Remove(key);
- }
- else
- throw new PoolNotRunException();//服务未启动
- }
- UpdateAttribute();//更新属性
- }
- #endregion
- //--------------------------------------------------------------------
- #region 私有方法
- private int createThreadMode = 0;//创建线程工作模式
- private int createThreadProcessTemp = 0;//需要创建的连接数
- private bool createThreadProcessRun = false;//是否决定创建线程将继续工作,如果不继续工作则线程会将自己处于阻止状态
- /// <summary>
- /// 创建线程
- /// </summary>
- private void createThreadProcess()
- {
- bool join = false;
- int createThreadProcessTemp_inside = createThreadProcessTemp;
- _ps = PoolState.Initialize;
- while (true)
- {
- join = false;
- _ps = PoolState.Run;
- if (createThreadProcessRun == false)
- {//遇到终止命令
- try { threadCreate.Join(); }
- catch (Exception e) { }
- }
- else
- {
- if (createThreadMode == 0)
- {
- //------------------------begin mode 创建模式
- lock (al_All)
- {
- if (al_All.Count < createThreadProcessTemp_inside)
- al_All.Add(CreateConnection(_connString, _connType));
- else
- join = true;
- }
- //------------------------end mode
- }
- else if (createThreadMode == 1)
- {
- //------------------------begin mode 增加模式
- lock (al_All)
- {
- if (createThreadProcessTemp_inside != 0)
- {
- createThreadProcessTemp_inside--;
- al_All.Add(CreateConnection(_connString, _connType));
- }
- else
- join = true;
- }
- //------------------------end mode
- }
- else
- join = true;
- //-------------------------------------------------------------------------
- if (join == true)
- {
- UpdateAttribute();//更新属性
- try
- {
- createThreadProcessTemp = 0;
- threadCreate.Join();
- }
- catch (Exception e)
- { createThreadProcessTemp_inside = createThreadProcessTemp; }//得到传入的变量
- }
- }
- }
- }
- /// <summary>
- /// 检测事件
- /// </summary>
- private void time_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
- {
- ConnStruct cs = null;
- time.Stop();//关闭自己
- isThreadCheckRun = true;
- //如果正在执行创建连接则退出
- if (threadCreate.ThreadState != ThreadState.WaitSleepJoin)
- return;
- //------------------------------------------------------
- lock (al_All)
- {
- int n = 0;
- for (int i = 0; i < al_All.Count; i++)
- {
- cs = al_All[i];
- TestConnStruct(cs);//测试
- if (cs.Enable == false && cs.RepeatNow == 0)//没有引用的失效连接
- {
- cs.Close();//关闭它
- al_All.Remove(cs);//删除
- }
- }
- }
- //------------------------------------------------------
- UpdateAttribute();//更新属性
- if (_spareRealFormPool < _keepRealConnection)//保留空闲实际连接数不足
- createThreadProcessTemp = GetNumOf(_realFormPool, _seepConnection, _maxConnection);
- else
- createThreadProcessTemp = 0;
- //if (createThreadProcessTemp != 0)
- // Console.WriteLine("创建" + createThreadProcessTemp);
- if (createThreadProcessTemp != 0)
- {
- //启动创建线程,工作模式1
- createThreadMode = 1;
- threadCreate.Interrupt();
- }
- isThreadCheckRun = false;
- time.Start();//打开自己
- }
- /// <summary>
- /// 得到当前要增加的量
- /// </summary>
- private int GetNumOf(int nowNum, int seepNum, int maxNum)
- {
- if (maxNum >= nowNum + seepNum)
- return seepNum;
- else
- return maxNum - nowNum;
- }
- /// <summary>
- /// 用指定类型创建连接
- /// </summary>
- /// <param name="conn">连接字符串</param>
- /// <param name="cte">连接类型</param>
- /// <param name="dt">连接超时时间</param>
- /// <returns>返回创建的连接</returns>
- private ConnStruct CreateConnection(string conn, ConnTypeEnum cte)
- {
- DbConnection db = null;
- if (cte == ConnTypeEnum.Odbc)
- db = new System.Data.Odbc.OdbcConnection(conn);//ODBC数据源连接
- else if (cte == ConnTypeEnum.OleDb)
- db = new System.Data.OleDb.OleDbConnection(conn);//OLE DB数据连接
- else if (cte == ConnTypeEnum.SqlClient)
- db = new System.Data.SqlClient.SqlConnection(conn);//SqlServer数据库连接
- ConnStruct cs = new ConnStruct(db, cte, DateTime.Now);
- cs.Open();
- return cs;
- }
- /// <summary>
- /// 测试ConnStruct是否过期
- /// </summary>
- /// <param name="cs">被测试的ConnStruct</param>
- private void TestConnStruct(ConnStruct cs)
- {
- //此次被分配出去的连接是否在此次之后失效
- if (cs.UseDegree == _maxRepeatDegree)
- cs.SetConnectionLost();//超过使用次数
- if (cs.CreateTime.AddMinutes(_exist).Ticks <= DateTime.Now.Ticks)
- cs.SetConnectionLost();//连接超时
- if (cs.Connection.State == ConnectionState.Closed)
- cs.SetConnectionLost();//连接被关闭
- }
- /// <summary>
- /// 更新属性
- /// </summary>
- private void UpdateAttribute()
- {
- int temp_readOnlyFormPool = 0;//连接池已经分配多少只读连接
- int temp_potentRealFormPool = 0;//连接池中存在的实际连接数(有效的实际连接)
- int temp_spareRealFormPool = 0;//空闲的实际连接
- int temp_useRealFormPool = 0;//已分配的实际连接
- int temp_spareFormPool = MaxConnectionFormPool;//目前可以提供的连接数
- //---------------------------------
- lock (hs_UseConn)
- {
- _useFormPool = hs_UseConn.Count;
- }
- //---------------------------------
- ConnStruct cs = null;
- int n = 0;
- lock (al_All)
- {
- _realFormPool = al_All.Count;
- for (int i = 0; i < al_All.Count; i++)
- {
- cs = al_All[i];
- //只读
- if (cs.Allot == false && cs.IsUse == true && cs.IsRepeat == false)
- temp_readOnlyFormPool++;
- //有效的实际连接
- if (cs.Enable == true)
- temp_potentRealFormPool++;
- //空闲的实际连接
- if (cs.Enable == true && cs.IsUse == false)
- temp_spareRealFormPool++;
- //已分配的实际连接
- if (cs.IsUse == true)
- temp_useRealFormPool++;
- //目前可以提供的连接数
- if (cs.Allot == true)
- temp_spareFormPool = temp_spareFormPool - cs.RepeatNow;
- else
- temp_spareFormPool = temp_spareFormPool - _maxRepeatDegree;
- }
- }
- _readOnlyFormPool = temp_readOnlyFormPool;
- _potentRealFormPool = temp_potentRealFormPool;
- _spareRealFormPool = temp_spareRealFormPool;
- _useRealFormPool = temp_useRealFormPool;
- _spareFormPool = temp_spareFormPool;
- }
- #endregion
- }
- }
|