diff --git a/Examples/dbcontext_01/Program.cs b/Examples/dbcontext_01/Program.cs index 0aa6a2a1..6f7b9727 100644 --- a/Examples/dbcontext_01/Program.cs +++ b/Examples/dbcontext_01/Program.cs @@ -40,7 +40,7 @@ namespace dbcontext_01 static IFreeSql fsql; public static void Main(string[] args) { - var asse = typeof(SafeObjectPool.ObjectPool<>).Assembly; + var asse = typeof(FreeSql.Internal.ObjectPool.ObjectPool<>).Assembly; fsql = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\dd2.db;Pooling=true;Max Pool Size=10") diff --git a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs index a05b8ba6..4e0aa3de 100644 --- a/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs +++ b/FreeSql.DbContext/UnitOfWork/UnitOfWork.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Collections.Concurrent; diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs index 2ad04f7d..67faf87a 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCall.cs @@ -1,16 +1,5 @@ -using FreeSql; -using FreeSql.DataAnnotations; +using FreeSql.DataAnnotations; using System; -using System.Collections; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Text; using System.Threading; [ExpressionCall] @@ -50,83 +39,4 @@ public static class FreeSqlGlobalExpressionCall expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} >= {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["that"]} < {expContext.Value.ParsedContent["end"]}"; return false; } - -#if netcoreapp - /// - /// C#:从元组集合中查找 exp1, exp2 是否存在 - /// SQL: - /// exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - /// exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - /// ... - /// 注意:当 that 为 null 或 empty 时,返回 1=0 - /// - /// - /// - /// - /// - /// - /// - public static bool Contains([RawValue] this IEnumerable<(T1, T2)> that, T1 exp1, T2 exp2) - { - if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) - return that?.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2)) == true; - if (that?.Any() != true) - { - expContext.Value.Result = "1=0"; - return false; - } - var sb = new StringBuilder(); - var idx = 0; - foreach (var item in that) - { - if (idx++ > 0) sb.Append(" OR \r\n"); - sb - .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))); - } - expContext.Value.Result = sb.ToString(); - return true; - } - /// - /// C#:从元组集合中查找 exp1, exp2, exp2 是否存在 - /// SQL: - /// exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - /// exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - /// ... - /// 注意:当 that 为 null 或 empty 时,返回 1=0 - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static bool Contains([RawValue] this IEnumerable<(T1, T2, T3)> that, T1 exp1, T2 exp2, T3 exp3) - { - if (expContext.IsValueCreated == false || expContext.Value == null || expContext.Value.ParsedContent == null) - return that.Any(a => a.Item1.Equals(exp1) && a.Item2.Equals(exp2) && a.Item3.Equals(exp3)); - if (that.Any() == false) - { - expContext.Value.Result = "1=0"; - return false; - } - var sb = new StringBuilder(); - var idx = 0; - foreach (var item in that) - { - if (idx++ > 0) sb.Append(" OR \r\n"); - sb - .Append(expContext.Value.ParsedContent["exp1"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T1), item.Item1))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp2"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T2), item.Item2))) - .Append(" AND ") - .Append(expContext.Value.ParsedContent["exp3"]).Append(" = ").Append(expContext.Value.FormatSql(FreeSql.Internal.Utils.GetDataReaderValue(typeof(T3), item.Item3))); - } - expContext.Value.Result = sb.ToString(); - return true; - } -#endif } \ No newline at end of file diff --git a/FreeSql/FreeSql.csproj b/FreeSql/FreeSql.csproj index 51229c77..c8887594 100644 --- a/FreeSql/FreeSql.csproj +++ b/FreeSql/FreeSql.csproj @@ -1,7 +1,7 @@  - netstandard2.0;netcoreapp31;netcoreapp30;netcoreapp22;netcoreapp21;net45;net40 + netstandard2.0;net45;net40 1.3.0-preview10 true YeXiangQin @@ -30,13 +30,6 @@ 3 - - - - - - netcoreapp - net40 diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 96d40ff9..cbd67953 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2900,6 +2900,225 @@ 中间表,多对多 + + + 是否可用 + + + + + 不可用错误 + + + + + 不可用时间 + + + + + 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + + + 由【可用】变成【不可用】时返回true,否则返回false + + + + 统计对象池中的对象 + + + + + 统计对象池中的对象(完整) + + + + + 获取资源 + + 超时 + + + + + 获取资源 + + + + + + 使用完毕后,归还资源 + + 对象 + 是否重新创建 + + + + 名称 + + + + + 池容量 + + + + + 默认获取超时设置 + + + + + 空闲时间,获取时若超出,则重新创建 + + + + + 异步获取排队队列大小,小于等于0不生效 + + + + + 获取超时后,是否抛出异常 + + + + + 后台定时检查可用性间隔秒数 + + + + + 对象池的对象被创建时 + + 返回被创建的对象 + + + + 销毁对象 + + 资源对象 + + + + 从对象池获取对象超时的时候触发,通过该方法统计 + + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + + + + 归还对象给对象池的时候触发 + + 资源对象 + + + + 检查可用性 + + 资源对象 + + + + + 事件:可用时触发 + + + + + 事件:不可用时触发 + + + + + 所属对象池 + + + + + 在对象池中的唯一标识 + + + + + 资源对象 + + + + + 被获取的总次数 + + + + 最后获取时的时间 + + + + 最后归还时的时间 + + + + + 创建时间 + + + + + 最后获取时的线程id + + + + + 最后归还时的线程id + + + + + 重置 Value 值 + + + + + 对象池管理类 + + 对象类型 + + + + 后台定时检查可用性 + + + + + + 创建对象池 + + 池大小 + 池内对象的创建委托 + 获取池内对象成功后,进行使用前操作 + + + + 创建对象池 + + 策略 + + + + 获取可用资源,或创建资源 + + + 不进行任何处理 @@ -2970,40 +3189,6 @@ - - - C#:从元组集合中查找 exp1, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - - C#:从元组集合中查找 exp1, exp2, exp2 是否存在 - SQL: - exp1 = that[0].Item1 and exp2 = that[0].Item2 and exp3 = that[0].Item3 OR - exp1 = that[1].Item1 and exp2 = that[1].Item2 and exp3 = that[1].Item3 OR - ... - 注意:当 that 为 null 或 empty 时,返回 1=0 - - - - - - - - - - 测量两个经纬度的距离,返回单位:米 diff --git a/FreeSql/FreeUtil.cs b/FreeSql/FreeUtil.cs index 145b8243..37e928c9 100644 --- a/FreeSql/FreeUtil.cs +++ b/FreeSql/FreeUtil.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Data.Common; diff --git a/FreeSql/Interface/IAdo.cs b/FreeSql/Interface/IAdo.cs index 3d93860d..d5ec0a8c 100644 --- a/FreeSql/Interface/IAdo.cs +++ b/FreeSql/Interface/IAdo.cs @@ -1,6 +1,6 @@ using FreeSql.DatabaseModel; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs index 2f2facd5..07d785ca 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProvider.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Collections.Concurrent; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs index bc8b96b6..356222af 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderAsync.cs @@ -1,5 +1,5 @@ using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs index 60133ed4..cd7356a5 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderTransaction.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs index d3be116e..e667b19f 100644 --- a/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs +++ b/FreeSql/Internal/CommonProvider/AdoProvider/DbConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonProvider/InsertProvider.cs b/FreeSql/Internal/CommonProvider/InsertProvider.cs index 3a15daab..d673a2af 100644 --- a/FreeSql/Internal/CommonProvider/InsertProvider.cs +++ b/FreeSql/Internal/CommonProvider/InsertProvider.cs @@ -1,6 +1,6 @@ using FreeSql.Internal.Model; using FreeSql.Extensions.EntityUtil; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs index 0f6d77d1..ddd24bf9 100644 --- a/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs +++ b/FreeSql/Internal/CommonProvider/InsertProviderAsync.cs @@ -1,5 +1,5 @@ using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/FreeSql/Internal/CommonUtils.cs b/FreeSql/Internal/CommonUtils.cs index cbab8e0a..14a5e3a6 100644 --- a/FreeSql/Internal/CommonUtils.cs +++ b/FreeSql/Internal/CommonUtils.cs @@ -2,7 +2,7 @@ using FreeSql.DatabaseModel; using FreeSql.Extensions.EntityUtil; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Concurrent; diff --git a/FreeSql/Internal/ObjectPool/DefaultPolicy.cs b/FreeSql/Internal/ObjectPool/DefaultPolicy.cs new file mode 100644 index 00000000..5541c579 --- /dev/null +++ b/FreeSql/Internal/ObjectPool/DefaultPolicy.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.ObjectPool +{ + + public class DefaultPolicy : IPolicy + { + + public string Name { get; set; } = typeof(DefaultPolicy).GetType().FullName; + public int PoolSize { get; set; } = 1000; + public TimeSpan SyncGetTimeout { get; set; } = TimeSpan.FromSeconds(10); + public TimeSpan IdleTimeout { get; set; } = TimeSpan.FromSeconds(50); + public int AsyncGetCapacity { get; set; } = 10000; + public bool IsThrowGetTimeoutException { get; set; } = true; + public int CheckAvailableInterval { get; set; } = 5; + + public Func CreateObject; + public Action> OnGetObject; + + public T OnCreate() + { + return CreateObject(); + } + + public void OnDestroy(T obj) + { + + } + + public void OnGet(Object obj) + { + //Console.WriteLine("Get: " + obj); + OnGetObject?.Invoke(obj); + } + +#if net40 +#else + public Task OnGetAsync(Object obj) + { + //Console.WriteLine("GetAsync: " + obj); + OnGetObject?.Invoke(obj); + return Task.FromResult(true); + } +#endif + + public void OnGetTimeout() + { + + } + + public void OnReturn(Object obj) + { + //Console.WriteLine("Return: " + obj); + } + + public bool OnCheckAvailable(Object obj) + { + return true; + } + + public void OnAvailable() + { + + } + + public void OnUnavailable() + { + + } + } +} \ No newline at end of file diff --git a/FreeSql/Internal/ObjectPool/IObjectPool.cs b/FreeSql/Internal/ObjectPool/IObjectPool.cs new file mode 100644 index 00000000..45644edb --- /dev/null +++ b/FreeSql/Internal/ObjectPool/IObjectPool.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.ObjectPool +{ + public interface IObjectPool : IDisposable + { + IPolicy Policy { get; } + /// + /// 是否可用 + /// + bool IsAvailable { get; } + /// + /// 不可用错误 + /// + Exception UnavailableException { get; } + /// + /// 不可用时间 + /// + DateTime? UnavailableTime { get; } + + /// + /// 将对象池设置为不可用,后续 Get/GetAsync 均会报错,同时启动后台定时检查服务恢复可用 + /// + /// + /// 由【可用】变成【不可用】时返回true,否则返回false + bool SetUnavailable(Exception exception); + + /// + /// 统计对象池中的对象 + /// + string Statistics { get; } + /// + /// 统计对象池中的对象(完整) + /// + string StatisticsFullily { get; } + + /// + /// 获取资源 + /// + /// 超时 + /// + Object Get(TimeSpan? timeout = null); + +#if net40 +#else + /// + /// 获取资源 + /// + /// + Task> GetAsync(); +#endif + + /// + /// 使用完毕后,归还资源 + /// + /// 对象 + /// 是否重新创建 + void Return(Object obj, bool isReset = false); + } +} diff --git a/FreeSql/Internal/ObjectPool/IPolicy.cs b/FreeSql/Internal/ObjectPool/IPolicy.cs new file mode 100644 index 00000000..63918587 --- /dev/null +++ b/FreeSql/Internal/ObjectPool/IPolicy.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace FreeSql.Internal.ObjectPool +{ + public interface IPolicy + { + + /// + /// 名称 + /// + string Name { get; set; } + + /// + /// 池容量 + /// + int PoolSize { get; set; } + + /// + /// 默认获取超时设置 + /// + TimeSpan SyncGetTimeout { get; set; } + + /// + /// 空闲时间,获取时若超出,则重新创建 + /// + TimeSpan IdleTimeout { get; set; } + + /// + /// 异步获取排队队列大小,小于等于0不生效 + /// + int AsyncGetCapacity { get; set; } + + /// + /// 获取超时后,是否抛出异常 + /// + bool IsThrowGetTimeoutException { get; set; } + + /// + /// 后台定时检查可用性间隔秒数 + /// + int CheckAvailableInterval { get; set; } + + /// + /// 对象池的对象被创建时 + /// + /// 返回被创建的对象 + T OnCreate(); + + /// + /// 销毁对象 + /// + /// 资源对象 + void OnDestroy(T obj); + + /// + /// 从对象池获取对象超时的时候触发,通过该方法统计 + /// + void OnGetTimeout(); + + /// + /// 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + /// + /// 资源对象 + void OnGet(Object obj); +#if net40 +#else + /// + /// 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + /// + /// 资源对象 + Task OnGetAsync(Object obj); +#endif + + /// + /// 归还对象给对象池的时候触发 + /// + /// 资源对象 + void OnReturn(Object obj); + + /// + /// 检查可用性 + /// + /// 资源对象 + /// + bool OnCheckAvailable(Object obj); + + /// + /// 事件:可用时触发 + /// + void OnAvailable(); + /// + /// 事件:不可用时触发 + /// + void OnUnavailable(); + } +} \ No newline at end of file diff --git a/FreeSql/Internal/ObjectPool/Object.cs b/FreeSql/Internal/ObjectPool/Object.cs new file mode 100644 index 00000000..cb76a49e --- /dev/null +++ b/FreeSql/Internal/ObjectPool/Object.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace FreeSql.Internal.ObjectPool +{ + + public class Object : IDisposable + { + public static Object InitWith(IObjectPool pool, int id, T value) + { + return new Object + { + Pool = pool, + Id = id, + Value = value, + LastGetThreadId = Thread.CurrentThread.ManagedThreadId, + LastGetTime = DateTime.Now + }; + } + + /// + /// 所属对象池 + /// + public IObjectPool Pool { get; internal set; } + + /// + /// 在对象池中的唯一标识 + /// + public int Id { get; internal set; } + /// + /// 资源对象 + /// + public T Value { get; internal set; } + + internal long _getTimes; + /// + /// 被获取的总次数 + /// + public long GetTimes => _getTimes; + + /// 最后获取时的时间 + public DateTime LastGetTime { get; internal set; } + + /// + /// 最后归还时的时间 + /// + public DateTime LastReturnTime { get; internal set; } + + /// + /// 创建时间 + /// + public DateTime CreateTime { get; internal set; } = DateTime.Now; + + /// + /// 最后获取时的线程id + /// + public int LastGetThreadId { get; internal set; } + + /// + /// 最后归还时的线程id + /// + public int LastReturnThreadId { get; internal set; } + + public override string ToString() + { + return $"{this.Value}, Times: {this.GetTimes}, ThreadId(R/G): {this.LastReturnThreadId}/{this.LastGetThreadId}, Time(R/G): {this.LastReturnTime.ToString("yyyy-MM-dd HH:mm:ss:ms")}/{this.LastGetTime.ToString("yyyy-MM-dd HH:mm:ss:ms")}"; + } + + /// + /// 重置 Value 值 + /// + public void ResetValue() + { + if (this.Value != null) + { + try { this.Pool.Policy.OnDestroy(this.Value); } catch { } + try { (this.Value as IDisposable)?.Dispose(); } catch { } + } + T value = default(T); + try { value = this.Pool.Policy.OnCreate(); } catch { } + this.Value = value; + this.LastReturnTime = DateTime.Now; + } + + internal bool _isReturned = false; + public void Dispose() + { + Pool?.Return(this); + } + } +} \ No newline at end of file diff --git a/FreeSql/Internal/ObjectPool/ObjectPool.cs b/FreeSql/Internal/ObjectPool/ObjectPool.cs new file mode 100644 index 00000000..2dc21f44 --- /dev/null +++ b/FreeSql/Internal/ObjectPool/ObjectPool.cs @@ -0,0 +1,547 @@ +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace FreeSql.Internal.ObjectPool +{ + + /// + /// 对象池管理类 + /// + /// 对象类型 + public partial class ObjectPool : IObjectPool + { + public IPolicy Policy { get; protected set; } + + private List> _allObjects = new List>(); + private object _allObjectsLock = new object(); + private ConcurrentStack> _freeObjects = new ConcurrentStack>(); + + private ConcurrentQueue _getSyncQueue = new ConcurrentQueue(); + private ConcurrentQueue>> _getAsyncQueue = new ConcurrentQueue>>(); + private ConcurrentQueue _getQueue = new ConcurrentQueue(); + + public bool IsAvailable => this.UnavailableException == null; + public Exception UnavailableException { get; private set; } + public DateTime? UnavailableTime { get; private set; } + private object UnavailableLock = new object(); + private bool running = true; + + public bool SetUnavailable(Exception exception) + { + + bool isseted = false; + + if (exception != null && UnavailableException == null) + { + + lock (UnavailableLock) + { + + if (UnavailableException == null) + { + + UnavailableException = exception; + UnavailableTime = DateTime.Now; + isseted = true; + } + } + } + + if (isseted) + { + + Policy.OnUnavailable(); + CheckAvailable(Policy.CheckAvailableInterval); + } + + return isseted; + } + + /// + /// 后台定时检查可用性 + /// + /// + private void CheckAvailable(int interval) + { + + new Thread(() => + { + + if (UnavailableException != null) + { + var bgcolor = Console.BackgroundColor; + var forecolor = Console.ForegroundColor; + Console.BackgroundColor = ConsoleColor.DarkYellow; + Console.ForegroundColor = ConsoleColor.White; + Console.Write($"【{Policy.Name}】恢复检查时间:{DateTime.Now.AddSeconds(interval)}"); + Console.BackgroundColor = bgcolor; + Console.ForegroundColor = forecolor; + Console.WriteLine(); + } + + while (UnavailableException != null) + { + + if (running == false) return; + + Thread.CurrentThread.Join(TimeSpan.FromSeconds(interval)); + + if (running == false) return; + + try + { + + var conn = getFree(false); + if (conn == null) throw new Exception($"CheckAvailable 无法获得资源,{this.Statistics}"); + + try + { + + if (Policy.OnCheckAvailable(conn) == false) throw new Exception("CheckAvailable 应抛出异常,代表仍然不可用。"); + break; + + } + finally + { + + Return(conn); + } + + } + catch (Exception ex) + { + var bgcolor = Console.BackgroundColor; + var forecolor = Console.ForegroundColor; + Console.BackgroundColor = ConsoleColor.DarkYellow; + Console.ForegroundColor = ConsoleColor.White; + Console.Write($"【{Policy.Name}】仍然不可用,下一次恢复检查时间:{DateTime.Now.AddSeconds(interval)},错误:({ex.Message})"); + Console.BackgroundColor = bgcolor; + Console.ForegroundColor = forecolor; + Console.WriteLine(); + } + } + + RestoreToAvailable(); + + }).Start(); + } + + private void RestoreToAvailable() + { + + bool isRestored = false; + if (UnavailableException != null) + { + + lock (UnavailableLock) + { + + if (UnavailableException != null) + { + + UnavailableException = null; + UnavailableTime = null; + isRestored = true; + } + } + } + + if (isRestored) + { + + lock (_allObjectsLock) + _allObjects.ForEach(a => a.LastGetTime = a.LastReturnTime = new DateTime(2000, 1, 1)); + + Policy.OnAvailable(); + + var bgcolor = Console.BackgroundColor; + var forecolor = Console.ForegroundColor; + Console.BackgroundColor = ConsoleColor.DarkGreen; + Console.ForegroundColor = ConsoleColor.White; + Console.Write($"【{Policy.Name}】已恢复工作"); + Console.BackgroundColor = bgcolor; + Console.ForegroundColor = forecolor; + Console.WriteLine(); + } + } + + protected bool LiveCheckAvailable() + { + + try + { + + var conn = getFree(false); + if (conn == null) throw new Exception($"LiveCheckAvailable 无法获得资源,{this.Statistics}"); + + try + { + + if (Policy.OnCheckAvailable(conn) == false) throw new Exception("LiveCheckAvailable 应抛出异常,代表仍然不可用。"); + + } + finally + { + + Return(conn); + } + + } + catch + { + return false; + } + + RestoreToAvailable(); + + return true; + } + + public string Statistics => $"Pool: {_freeObjects.Count}/{_allObjects.Count}, Get wait: {_getSyncQueue.Count}, GetAsync wait: {_getAsyncQueue.Count}"; + public string StatisticsFullily + { + get + { + var sb = new StringBuilder(); + + sb.AppendLine(Statistics); + sb.AppendLine(""); + + foreach (var obj in _allObjects) + { + sb.AppendLine($"{obj.Value}, Times: {obj.GetTimes}, ThreadId(R/G): {obj.LastReturnThreadId}/{obj.LastGetThreadId}, Time(R/G): {obj.LastReturnTime.ToString("yyyy-MM-dd HH:mm:ss:ms")}/{obj.LastGetTime.ToString("yyyy-MM-dd HH:mm:ss:ms")}, "); + } + + return sb.ToString(); + } + } + + /// + /// 创建对象池 + /// + /// 池大小 + /// 池内对象的创建委托 + /// 获取池内对象成功后,进行使用前操作 + public ObjectPool(int poolsize, Func createObject, Action> onGetObject = null) : this(new DefaultPolicy { PoolSize = poolsize, CreateObject = createObject, OnGetObject = onGetObject }) + { + } + /// + /// 创建对象池 + /// + /// 策略 + public ObjectPool(IPolicy policy) + { + Policy = policy; + + AppDomain.CurrentDomain.ProcessExit += (s1, e1) => + { + running = false; + }; + try + { + Console.CancelKeyPress += (s1, e1) => + { + if (e1.Cancel) return; + running = false; + }; + } + catch { } + } + + /// + /// 获取可用资源,或创建资源 + /// + /// + private Object getFree(bool checkAvailable) + { + + if (running == false) + throw new ObjectDisposedException($"【{Policy.Name}】对象池已释放,无法访问。"); + + if (checkAvailable && UnavailableException != null) + throw new Exception($"【{Policy.Name}】状态不可用,等待后台检查程序恢复方可使用。{UnavailableException?.Message}"); + + if ((_freeObjects.TryPop(out var obj) == false || obj == null) && _allObjects.Count < Policy.PoolSize) + { + + lock (_allObjectsLock) + if (_allObjects.Count < Policy.PoolSize) + _allObjects.Add(obj = new Object { Pool = this, Id = _allObjects.Count + 1 }); + } + + if (obj != null) + obj._isReturned = false; + + if (obj != null && obj.Value == null || + obj != null && Policy.IdleTimeout > TimeSpan.Zero && DateTime.Now.Subtract(obj.LastReturnTime) > Policy.IdleTimeout) + { + try + { + obj.ResetValue(); + } + catch + { + Return(obj); + throw; + } + } + + return obj; + } + + public Object Get(TimeSpan? timeout = null) + { + + var obj = getFree(true); + + if (obj == null) + { + + var queueItem = new GetSyncQueueInfo(); + + _getSyncQueue.Enqueue(queueItem); + _getQueue.Enqueue(false); + + if (timeout == null) timeout = Policy.SyncGetTimeout; + + try + { + if (queueItem.Wait.Wait(timeout.Value)) + obj = queueItem.ReturnValue; + } + catch { } + + if (obj == null) obj = queueItem.ReturnValue; + if (obj == null) lock (queueItem.Lock) queueItem.IsTimeout = (obj = queueItem.ReturnValue) == null; + if (obj == null) obj = queueItem.ReturnValue; + + if (obj == null) + { + + Policy.OnGetTimeout(); + + if (Policy.IsThrowGetTimeoutException) + throw new TimeoutException($"SafeObjectPool.Get 获取超时({timeout.Value.TotalSeconds}秒)。"); + + return null; + } + } + + try + { + Policy.OnGet(obj); + } + catch + { + Return(obj); + throw; + } + + obj.LastGetThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastGetTime = DateTime.Now; + Interlocked.Increment(ref obj._getTimes); + + return obj; + } + +#if net40 +#else + async public Task> GetAsync() + { + + var obj = getFree(true); + + if (obj == null) + { + + if (Policy.AsyncGetCapacity > 0 && _getAsyncQueue.Count >= Policy.AsyncGetCapacity - 1) + throw new OutOfMemoryException($"SafeObjectPool.GetAsync 无可用资源且队列过长,Policy.AsyncGetCapacity = {Policy.AsyncGetCapacity}。"); + + var tcs = new TaskCompletionSource>(); + + _getAsyncQueue.Enqueue(tcs); + _getQueue.Enqueue(true); + + obj = await tcs.Task; + + //if (timeout == null) timeout = Policy.SyncGetTimeout; + + //if (tcs.Task.Wait(timeout.Value)) + // obj = tcs.Task.Result; + + //if (obj == null) { + + // tcs.TrySetCanceled(); + // Policy.GetTimeout(); + + // if (Policy.IsThrowGetTimeoutException) + // throw new Exception($"SafeObjectPool.GetAsync 获取超时({timeout.Value.TotalSeconds}秒)。"); + + // return null; + //} + } + + try + { + await Policy.OnGetAsync(obj); + } + catch + { + Return(obj); + throw; + } + + obj.LastGetThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastGetTime = DateTime.Now; + Interlocked.Increment(ref obj._getTimes); + + return obj; + } +#endif + + public void Return(Object obj, bool isReset = false) + { + + if (obj == null) return; + + if (obj._isReturned) return; + + if (running == false) + { + + Policy.OnDestroy(obj.Value); + try { (obj.Value as IDisposable)?.Dispose(); } catch { } + + return; + } + + if (isReset) obj.ResetValue(); + + bool isReturn = false; + + while (isReturn == false && _getQueue.TryDequeue(out var isAsync)) + { + + if (isAsync == false) + { + + if (_getSyncQueue.TryDequeue(out var queueItem) && queueItem != null) + { + + lock (queueItem.Lock) + if (queueItem.IsTimeout == false) + queueItem.ReturnValue = obj; + + if (queueItem.ReturnValue != null) + { + + obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastReturnTime = DateTime.Now; + + try + { + queueItem.Wait.Set(); + isReturn = true; + } + catch + { + } + } + + try { queueItem.Dispose(); } catch { } + } + + } + else + { + + if (_getAsyncQueue.TryDequeue(out var tcs) && tcs != null && tcs.Task.IsCanceled == false) + { + + obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastReturnTime = DateTime.Now; + + try { isReturn = tcs.TrySetResult(obj); } catch { } + } + } + } + + //无排队,直接归还 + if (isReturn == false) + { + try + { + Policy.OnReturn(obj); + } + catch + { + throw; + } + finally + { + obj.LastReturnThreadId = Thread.CurrentThread.ManagedThreadId; + obj.LastReturnTime = DateTime.Now; + obj._isReturned = true; + + _freeObjects.Push(obj); + } + } + } + + public void Dispose() + { + + running = false; + + while (_freeObjects.TryPop(out var fo)) ; + + while (_getSyncQueue.TryDequeue(out var sync)) + { + try { sync.Wait.Set(); } catch { } + } + + while (_getAsyncQueue.TryDequeue(out var async)) + async.TrySetCanceled(); + + while (_getQueue.TryDequeue(out var qs)) ; + + for (var a = 0; a < _allObjects.Count; a++) + { + Policy.OnDestroy(_allObjects[a].Value); + try { (_allObjects[a].Value as IDisposable)?.Dispose(); } catch { } + } + + _allObjects.Clear(); + } + + class GetSyncQueueInfo : IDisposable + { + + internal ManualResetEventSlim Wait { get; set; } = new ManualResetEventSlim(); + + internal Object ReturnValue { get; set; } + + internal object Lock = new object(); + + internal bool IsTimeout { get; set; } = false; + + public void Dispose() + { + try + { + if (Wait != null) + Wait.Dispose(); + } + catch + { + } + } + } + } +} \ No newline at end of file diff --git a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs index 012931a7..987a05ca 100644 --- a/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs +++ b/Providers/FreeSql.Provider.MsAccess/Curd/MsAccessInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs index f6f8844b..195dbb9d 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs index 4ae88c92..f28cc00a 100644 --- a/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs +++ b/Providers/FreeSql.Provider.MsAccess/MsAccessAdo/MsAccessConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs index e95438d1..d6df8d17 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlAdo.cs @@ -1,7 +1,7 @@ using FreeSql.Internal; using FreeSql.Internal.Model; using MySql.Data.MySqlClient; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs index 61fb63f4..86cb81ec 100644 --- a/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.MySql/MySqlAdo/MySqlConnectionPool.cs @@ -1,5 +1,5 @@ using MySql.Data.MySqlClient; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs index 34c3529c..f485abe1 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs index a6a23395..9bb0051d 100644 --- a/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Dameng/OdbcDamengAdo/OdbcDamengConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs index dddd0cf0..3abd6fd4 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/Curd/OdbcInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs index 32b028f7..f11b8b10 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs index 4ce05dd8..8e6fb010 100644 --- a/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Default/OdbcAdo/OdbcConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs index 41b4b0bf..88a9c9b5 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/Curd/OdbcMySqlInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs index d9738cc6..94921b95 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs index a9a044cc..c3e07c5d 100644 --- a/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/MySql/OdbcMySqlAdo/OdbcMySqlConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs index fabfcddd..bb33aa87 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs index 06f358fe..ddf1e6e4 100644 --- a/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/Oracle/OdbcOracleAdo/OdbcOracleConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs index c0ac2ae6..60361f3e 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs index 2230fbc3..62e08f02 100644 --- a/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/PostgreSQL/OdbcPostgreSQLAdo/OdbcPostgreSQLConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs index d134cfe0..8c8fd511 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/Curd/OdbcSqlServerInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs index d97d5fc1..9f2f291e 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs index d068a424..dab55b93 100644 --- a/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.Odbc/SqlServer/OdbcSqlServerAdo/OdbcSqlServerConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs index ba81e59c..791f4f7b 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleAdo.cs @@ -1,7 +1,7 @@ using FreeSql.Internal; using FreeSql.Internal.Model; using Oracle.ManagedDataAccess.Client; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs index c088d63a..09b82011 100644 --- a/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs +++ b/Providers/FreeSql.Provider.Oracle/OracleAdo/OracleConnectionPool.cs @@ -1,5 +1,5 @@ using Oracle.ManagedDataAccess.Client; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs index d843b497..5f1600b9 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLAdo.cs @@ -2,7 +2,7 @@ using FreeSql.Internal.Model; using Newtonsoft.Json.Linq; using Npgsql; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs index 007bc36b..958420ef 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLAdo/PostgreSQLConnectionPool.cs @@ -1,5 +1,5 @@ using Npgsql; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs index f10093c2..f5cbc3a0 100644 --- a/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs +++ b/Providers/FreeSql.Provider.PostgreSQL/PostgreSQLDbFirst.cs @@ -3,7 +3,7 @@ using FreeSql.Internal; using Newtonsoft.Json.Linq; using Npgsql.LegacyPostgis; using NpgsqlTypes; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs index 36dd6f17..c99cbbb6 100644 --- a/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs +++ b/Providers/FreeSql.Provider.SqlServer/Curd/SqlServerInsert.cs @@ -1,5 +1,5 @@ using FreeSql.Internal; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Generic; using System.Data; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs index 5ca513c1..08bce9b7 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data.Common; diff --git a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs index 7e5496fd..1e9e060a 100644 --- a/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs +++ b/Providers/FreeSql.Provider.SqlServer/SqlServerAdo/SqlServerConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs index 09ba12df..357b87b8 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteAdo.cs @@ -1,6 +1,6 @@ using FreeSql.Internal; using FreeSql.Internal.Model; -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections; using System.Data; diff --git a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs index 10baf6f0..828ca70d 100644 --- a/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs +++ b/Providers/FreeSql.Provider.Sqlite/SqliteAdo/SqliteConnectionPool.cs @@ -1,4 +1,4 @@ -using SafeObjectPool; +using FreeSql.Internal.ObjectPool; using System; using System.Collections.Concurrent; using System.Collections.Generic;