commits列表 30 项
提交内容 36/36
添加excel导出模式!基于配置,string[]自动添加split特性!消除警告,后续再写文档!
example/ExampleApeart.Handler/eventmodels/EventDemoModelHandler.cs
diff --git a/example/ExampleApeart.Handler/eventmodels/EventDemoModelHandler.cs b/example/ExampleApeart.Handler/eventmodels/EventDemoModelHandler.cs
index a2e722b..bc4c2fc 100644
--- a/example/ExampleApeart.Handler/eventmodels/EventDemoModelHandler.cs
+++ b/example/ExampleApeart.Handler/eventmodels/EventDemoModelHandler.cs
@@ -1,6 +1,5 @@
 using ExampleApeart.Application.Contracts.eventmodels;
 using Microsoft.Extensions.Logging;
-using PasteApeart;
 using PasteApeart.Dependency;
 using PasteApeart.Handler;
 using PasteApeart.Handler.Extensions;
@@ -32,7 +31,10 @@ namespace ExampleApeart.Handler.eventmodels
             _channelHelper = channelHelper;
         }
 
-
+        /// <summary>
+        /// 
+        /// </summary>
+        public object Result { get; protected set; }
 
         /// <summary>
         /// 
framework/Directory.Build.props
diff --git a/framework/Directory.Build.props b/framework/Directory.Build.props
index b6669d0..b8f4d75 100644
--- a/framework/Directory.Build.props
+++ b/framework/Directory.Build.props
@@ -1,7 +1,7 @@
 <Project>
   <PropertyGroup>
-    <Version>26.10.02</Version>
-    <FileVersion>26.10.02</FileVersion>
-    <AssemblyVersion>26.10.02</AssemblyVersion>
+    <Version>26.10.04</Version>
+    <FileVersion>26.10.04</FileVersion>
+    <AssemblyVersion>26.10.04</AssemblyVersion>
   </PropertyGroup>
 </Project>
\ No newline at end of file
framework/PasteApeart.Dependency/IScopedDependency.cs
diff --git a/framework/PasteApeart.Dependency/IScopedDependency.cs b/framework/PasteApeart.Dependency/IScopedDependency.cs
index 50b06ff..fa9765e 100644
--- a/framework/PasteApeart.Dependency/IScopedDependency.cs
+++ b/framework/PasteApeart.Dependency/IScopedDependency.cs
@@ -1,8 +1,14 @@
 namespace PasteApeart.Dependency
 {
+    /// <summary>
+    /// 会话模式
+    /// </summary>
     public interface IScopedDependency
     {
     }
+    /// <summary>
+    /// 会话模式
+    /// </summary>
     public interface IScoped
     {
     }
framework/PasteApeart.Dependency/ISingletonDependency.cs
diff --git a/framework/PasteApeart.Dependency/ISingletonDependency.cs b/framework/PasteApeart.Dependency/ISingletonDependency.cs
index cb3e1cb..fde0b22 100644
--- a/framework/PasteApeart.Dependency/ISingletonDependency.cs
+++ b/framework/PasteApeart.Dependency/ISingletonDependency.cs
@@ -1,11 +1,17 @@
 namespace PasteApeart.Dependency
 {
 
-
+    /// <summary>
+    /// 单例模式
+    /// </summary>
     public interface ISingletonDependency
     {
 
     }
+
+    /// <summary>
+    /// 单例模式
+    /// </summary>
     public interface ISingleton
     {
 
framework/PasteApeart.Dependency/ITransientDependency.cs
diff --git a/framework/PasteApeart.Dependency/ITransientDependency.cs b/framework/PasteApeart.Dependency/ITransientDependency.cs
index 3d754c8..f095ef2 100644
--- a/framework/PasteApeart.Dependency/ITransientDependency.cs
+++ b/framework/PasteApeart.Dependency/ITransientDependency.cs
@@ -1,11 +1,17 @@
 namespace PasteApeart.Dependency
 {
 
+    /// <summary>
+    /// 瞬时
+    /// </summary>
     public interface ITransientDependency
     {
 
     }
 
+    /// <summary>
+    /// 瞬时
+    /// </summary>
     public interface ITransient
     {
 
framework/PasteApeart.Dependency/PasteApeart.Dependency.csproj
diff --git a/framework/PasteApeart.Dependency/PasteApeart.Dependency.csproj b/framework/PasteApeart.Dependency/PasteApeart.Dependency.csproj
index d3dc50e..a0c478a 100644
--- a/framework/PasteApeart.Dependency/PasteApeart.Dependency.csproj
+++ b/framework/PasteApeart.Dependency/PasteApeart.Dependency.csproj
@@ -12,6 +12,7 @@
 		<PackageLicenseExpression>MIT</PackageLicenseExpression>
 		<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
 		<GenerateDocumentationFile>True</GenerateDocumentationFile>
+		<DocumentationFile>PasteApeart.Dependency.xml</DocumentationFile>
 	</PropertyGroup>
 	<ItemGroup>
 		<None Include="readme.md" Pack="true" PackagePath="/" Visible="true" />
framework/PasteApeart.Dependency/PasteApeart.Dependency.xm
diff --git a/framework/PasteApeart.Dependency/PasteApeart.Dependency.xm b/framework/PasteApeart.Dependency/PasteApeart.Dependency.xm
new file mode 100644
index 0000000..a4c4204
--- /dev/null
+++ b/framework/PasteApeart.Dependency/PasteApeart.Dependency.xm
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>PasteApeart.Dependency</name>
+    </assembly>
+    <members>
+        <member name="T:PasteApeart.Dependency.AutoDependencyExtensions">
+            <summary>
+            自动执行注入
+            </summary>
+        </member>
+        <member name="M:PasteApeart.Dependency.AutoDependencyExtensions.AddAutoDependency(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Reflection.Assembly)">
+            <summary>
+            扫描注入 瞬时 作用域 单例等 ITransient ISingleton IScoped
+            </summary>
+            <param name="services"></param>
+            <param name="assembly"></param>
+            <returns></returns>
+        </member>
+        <member name="T:PasteApeart.Dependency.AutoDependencyInjectionExtensions">
+            <summary>
+            自动执行注入
+            </summary>
+        </member>
+        <member name="M:PasteApeart.Dependency.AutoDependencyInjectionExtensions.AddAutoDependencyInjection(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Reflection.Assembly)">
+            <summary>
+            扫描注入 瞬时 作用域 单例等
+            </summary>
+            <param name="services"></param>
+            <param name="assembly"></param>
+            <returns></returns>
+        </member>
+        <member name="T:PasteApeart.Dependency.IScopedDependency">
+            <summary>
+            会话模式
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.IScoped">
+            <summary>
+            会话模式
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.ISingletonDependency">
+            <summary>
+            单例模式
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.ISingleton">
+            <summary>
+            单例模式
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.ITransientDependency">
+            <summary>
+            瞬时
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.ITransient">
+            <summary>
+            瞬时
+            </summary>
+        </member>
+    </members>
+</doc>
framework/PasteApeart.Dependency/PasteApeart.Dependency.xml
diff --git a/framework/PasteApeart.Dependency/PasteApeart.Dependency.xml b/framework/PasteApeart.Dependency/PasteApeart.Dependency.xml
new file mode 100644
index 0000000..a4c4204
--- /dev/null
+++ b/framework/PasteApeart.Dependency/PasteApeart.Dependency.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>PasteApeart.Dependency</name>
+    </assembly>
+    <members>
+        <member name="T:PasteApeart.Dependency.AutoDependencyExtensions">
+            <summary>
+            自动执行注入
+            </summary>
+        </member>
+        <member name="M:PasteApeart.Dependency.AutoDependencyExtensions.AddAutoDependency(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Reflection.Assembly)">
+            <summary>
+            扫描注入 瞬时 作用域 单例等 ITransient ISingleton IScoped
+            </summary>
+            <param name="services"></param>
+            <param name="assembly"></param>
+            <returns></returns>
+        </member>
+        <member name="T:PasteApeart.Dependency.AutoDependencyInjectionExtensions">
+            <summary>
+            自动执行注入
+            </summary>
+        </member>
+        <member name="M:PasteApeart.Dependency.AutoDependencyInjectionExtensions.AddAutoDependencyInjection(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Reflection.Assembly)">
+            <summary>
+            扫描注入 瞬时 作用域 单例等
+            </summary>
+            <param name="services"></param>
+            <param name="assembly"></param>
+            <returns></returns>
+        </member>
+        <member name="T:PasteApeart.Dependency.IScopedDependency">
+            <summary>
+            会话模式
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.IScoped">
+            <summary>
+            会话模式
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.ISingletonDependency">
+            <summary>
+            单例模式
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.ISingleton">
+            <summary>
+            单例模式
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.ITransientDependency">
+            <summary>
+            瞬时
+            </summary>
+        </member>
+        <member name="T:PasteApeart.Dependency.ITransient">
+            <summary>
+            瞬时
+            </summary>
+        </member>
+    </members>
+</doc>
framework/PasteApeart.Handler/JsonConfig.cs
diff --git a/framework/PasteApeart.Handler/JsonConfig.cs b/framework/PasteApeart.Handler/JsonConfig.cs
index b9664e5..503c3b9 100644
--- a/framework/PasteApeart.Handler/JsonConfig.cs
+++ b/framework/PasteApeart.Handler/JsonConfig.cs
@@ -1,4 +1,4 @@
-using System.Globalization;
+using System.Globalization;
 using System.Text.Encodings.Web;
 using System.Text.Json;
 using System.Text.Json.Serialization;
@@ -90,12 +90,21 @@ namespace PasteApeart.Handler
             }
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="writer"></param>
+        /// <param name="value"></param>
+        /// <param name="options"></param>
         public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
         {
             writer.WriteStringValue(value);
         }
     }
 
+    /// <summary>
+    /// 
+    /// </summary>
     public class SafeDateTimeConverter : JsonConverter<DateTime>
     {
         // 支持的常见日期时间格式
@@ -132,6 +141,14 @@ namespace PasteApeart.Handler
             }
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="reader"></param>
+        /// <param name="typeToConvert"></param>
+        /// <param name="options"></param>
+        /// <returns></returns>
+        /// <exception cref="JsonException"></exception>
         public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
         {
             if (reader.TokenType == JsonTokenType.String)
@@ -175,6 +192,12 @@ namespace PasteApeart.Handler
             throw new JsonException($"意外的 token 类型: {reader.TokenType},期望字符串或数字");
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="writer"></param>
+        /// <param name="value"></param>
+        /// <param name="options"></param>
         public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
         {
             // 输出使用标准格式
framework/PasteApeart.Handler/PasteApeartHandlerModule.cs
diff --git a/framework/PasteApeart.Handler/PasteApeartHandlerModule.cs b/framework/PasteApeart.Handler/PasteApeartHandlerModule.cs
index cbaa66b..76cf440 100644
--- a/framework/PasteApeart.Handler/PasteApeartHandlerModule.cs
+++ b/framework/PasteApeart.Handler/PasteApeartHandlerModule.cs
@@ -6,7 +6,9 @@ using PasteApeart.Handler.rabbit;
 namespace PasteApeart.Handler
 {
 
-
+    /// <summary>
+    /// 
+    /// </summary>
     public static class PasteApeartHandlerModule
     {
 
framework/PasteApeart.Handler/SerilogCustomHandler.cs
diff --git a/framework/PasteApeart.Handler/SerilogCustomHandler.cs b/framework/PasteApeart.Handler/SerilogCustomHandler.cs
index 91f9be3..269bf0d 100644
--- a/framework/PasteApeart.Handler/SerilogCustomHandler.cs
+++ b/framework/PasteApeart.Handler/SerilogCustomHandler.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -9,6 +9,9 @@ using Serilog.Events;
 
 namespace PasteApeart.Handler
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public class SerilogCustomHandler : ILogEventSink
     {
         /// <summary>
framework/PasteApeart.Handler/aevent/AbsEventModelExtensions.cs
diff --git a/framework/PasteApeart.Handler/aevent/AbsEventModelExtensions.cs b/framework/PasteApeart.Handler/aevent/AbsEventModelExtensions.cs
index 0423f8b..7145389 100644
--- a/framework/PasteApeart.Handler/aevent/AbsEventModelExtensions.cs
+++ b/framework/PasteApeart.Handler/aevent/AbsEventModelExtensions.cs
@@ -122,9 +122,10 @@ namespace PasteApeart.Handler
         }
 
         /// <summary>
-        /// 设置下一次执行时间 并压入到队列
+        /// 
         /// </summary>
         /// <param name="input"></param>
+        /// <param name="_channelHelper"></param>
         /// <returns></returns>
         public static async Task<bool> ToAutoExpireAndSendAsync(this AbsEventModel input, IChannelHelper _channelHelper)
         {
framework/PasteApeart.Handler/aevent/IEventHandler.cs
diff --git a/framework/PasteApeart.Handler/aevent/IEventHandler.cs b/framework/PasteApeart.Handler/aevent/IEventHandler.cs
index 7d08208..33d907f 100644
--- a/framework/PasteApeart.Handler/aevent/IEventHandler.cs
+++ b/framework/PasteApeart.Handler/aevent/IEventHandler.cs
@@ -1,9 +1,4 @@
 using PasteApeart.Application.Contracts;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace PasteApeart.Handler
 {
@@ -20,5 +15,11 @@ namespace PasteApeart.Handler
         /// <param name="input"></param>
         /// <returns></returns>
         Task HandleEventAsync(EventModel input);
+
+        /// <summary>
+        /// 处理器执行结果,供主动调用方读取。
+        /// 系统运行时通常为 null。
+        /// </summary>
+        object Result { get; }
     }
 }
framework/PasteApeart.Handler/basic/ApeartExtensions.cs
diff --git a/framework/PasteApeart.Handler/basic/ApeartExtensions.cs b/framework/PasteApeart.Handler/basic/ApeartExtensions.cs
index 9954c88..3e7879e 100644
--- a/framework/PasteApeart.Handler/basic/ApeartExtensions.cs
+++ b/framework/PasteApeart.Handler/basic/ApeartExtensions.cs
@@ -93,41 +93,44 @@ namespace PasteApeart.Handler
                 : source;
         }
 
-        //
-        // 摘要:
-        //     Used for paging. Can be used as an alternative to Skip(...).Take(...) chaining.
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="skipCount"></param>
+        /// <param name="maxResultCount"></param>
+        /// <returns></returns>
         public static IQueryable<T> PastePageBy<T>(this IQueryable<T> query, int skipCount, int maxResultCount)
         {
             Check.PasteNotNull(query, "query");
             return query.Skip(skipCount).Take(maxResultCount);
         }
 
-        //
-        // 摘要:
-        //     Used for paging. Can be used as an alternative to Skip(...).Take(...) chaining.
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="TQueryable"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="skipCount"></param>
+        /// <param name="maxResultCount"></param>
+        /// <returns></returns>
         public static TQueryable PastePageBy<T, TQueryable>(this TQueryable query, int skipCount, int maxResultCount) where TQueryable : IQueryable<T>
         {
             Check.PasteNotNull(query, "query");
             return (TQueryable)query.Skip(skipCount).Take(maxResultCount);
         }
 
-        //
-        // 摘要:
-        //     Filters a System.Linq.IQueryable`1 by given predicate if given condition is true.
-        //
-        //
-        // 参数:
-        //   query:
-        //     Queryable to apply filtering
-        //
-        //   condition:
-        //     A boolean value
-        //
-        //   predicate:
-        //     Predicate to filter the query
-        //
-        // 返回结果:
-        //     Filtered or not filtered query based on condition
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="condition"></param>
+        /// <param name="predicate"></param>
+        /// <returns></returns>
         public static IQueryable<T> PasteWhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
         {
             Check.PasteNotNull(query, "query");
@@ -139,23 +142,16 @@ namespace PasteApeart.Handler
             return query.Where(predicate);
         }
 
-        //
-        // 摘要:
-        //     Filters a System.Linq.IQueryable`1 by given predicate if given condition is true.
-        //
-        //
-        // 参数:
-        //   query:
-        //     Queryable to apply filtering
-        //
-        //   condition:
-        //     A boolean value
-        //
-        //   predicate:
-        //     Predicate to filter the query
-        //
-        // 返回结果:
-        //     Filtered or not filtered query based on condition
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="TQueryable"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="condition"></param>
+        /// <param name="predicate"></param>
+        /// <returns></returns>
         public static TQueryable PasteWhereIf<T, TQueryable>(this TQueryable query, bool condition, Expression<Func<T, bool>> predicate) where TQueryable : IQueryable<T>
         {
             Check.PasteNotNull(query, "query");
@@ -167,23 +163,15 @@ namespace PasteApeart.Handler
             return (TQueryable)query.Where(predicate);
         }
 
-        //
-        // 摘要:
-        //     Filters a System.Linq.IQueryable`1 by given predicate if given condition is true.
-        //
-        //
-        // 参数:
-        //   query:
-        //     Queryable to apply filtering
-        //
-        //   condition:
-        //     A boolean value
-        //
-        //   predicate:
-        //     Predicate to filter the query
-        //
-        // 返回结果:
-        //     Filtered or not filtered query based on condition
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="condition"></param>
+        /// <param name="predicate"></param>
+        /// <returns></returns>
         public static IQueryable<T> PasteWhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, int, bool>> predicate)
         {
             Check.PasteNotNull(query, "query");
@@ -195,23 +183,16 @@ namespace PasteApeart.Handler
             return query.Where(predicate);
         }
 
-        //
-        // 摘要:
-        //     Filters a System.Linq.IQueryable`1 by given predicate if given condition is true.
-        //
-        //
-        // 参数:
-        //   query:
-        //     Queryable to apply filtering
-        //
-        //   condition:
-        //     A boolean value
-        //
-        //   predicate:
-        //     Predicate to filter the query
-        //
-        // 返回结果:
-        //     Filtered or not filtered query based on condition
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="TQueryable"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="condition"></param>
+        /// <param name="predicate"></param>
+        /// <returns></returns>
         public static TQueryable PasteWhereIf<T, TQueryable>(this TQueryable query, bool condition, Expression<Func<T, int, bool>> predicate) where TQueryable : IQueryable<T>
         {
             Check.PasteNotNull(query, "query");
framework/PasteApeart.Handler/cache/CacheHandler.cs
diff --git a/framework/PasteApeart.Handler/cache/CacheHandler.cs b/framework/PasteApeart.Handler/cache/CacheHandler.cs
index fdd5e3e..a85b569 100644
--- a/framework/PasteApeart.Handler/cache/CacheHandler.cs
+++ b/framework/PasteApeart.Handler/cache/CacheHandler.cs
@@ -17,7 +17,6 @@ namespace PasteApeart.Handler.cache
         /// </summary>
         /// <param name="serviceProvider"></param>
         /// <param name="cache"></param>
-        /// <param name="map"></param>
         public CacheHandler(DbContext serviceProvider, IAppCache cache)
         {
             _dbContext = serviceProvider;
framework/PasteApeart.Handler/cache/ICacheHandler.cs
diff --git a/framework/PasteApeart.Handler/cache/ICacheHandler.cs b/framework/PasteApeart.Handler/cache/ICacheHandler.cs
index 388d2b4..f98205e 100644
--- a/framework/PasteApeart.Handler/cache/ICacheHandler.cs
+++ b/framework/PasteApeart.Handler/cache/ICacheHandler.cs
@@ -1,6 +1,9 @@
 
 namespace PasteApeart.Handler.cache
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public interface ICacheHandler
     {
         /// <summary>
framework/PasteApeart.Handler/common/ChannelHelper.cs
diff --git a/framework/PasteApeart.Handler/common/ChannelHelper.cs b/framework/PasteApeart.Handler/common/ChannelHelper.cs
index 608be0f..62267aa 100644
--- a/framework/PasteApeart.Handler/common/ChannelHelper.cs
+++ b/framework/PasteApeart.Handler/common/ChannelHelper.cs
@@ -139,6 +139,7 @@ namespace PasteApeart.Handler
         /// </summary>
         /// <typeparam name="T"></typeparam>
         /// <param name="input"></param>
+        /// <param name="id"></param>
         /// <returns></returns>
         [Obsolete("use WriteAutoQueueAsync before new MutexKey")]
         public async Task WriteMutexMQAsync<T>(T input, object id) where T : IEventModel
framework/PasteApeart.Handler/common/EventActionHandler.cs
diff --git a/framework/PasteApeart.Handler/common/EventActionHandler.cs b/framework/PasteApeart.Handler/common/EventActionHandler.cs
index f9782a2..b83a5d4 100644
--- a/framework/PasteApeart.Handler/common/EventActionHandler.cs
+++ b/framework/PasteApeart.Handler/common/EventActionHandler.cs
@@ -25,6 +25,7 @@ namespace PasteApeart.Handler
         /// <param name="logger"></param>
         /// <param name="serviceProvider"></param>
         /// <param name="channelHelper"></param>
+        /// <param name="dtoTypes"></param>
         public EventActionHandler(ILogger<EventActionHandler> logger, IServiceProvider serviceProvider, IChannelHelper channelHelper, Type[] dtoTypes = null)
         {
             _logger = logger;
@@ -59,7 +60,7 @@ namespace PasteApeart.Handler
                 return;
             }
 
-            await ActionAsync(msg, _dtoTypeArray);
+            await ActionReturnResultAsync(msg, _dtoTypeArray);
         }
 
         /// <summary>
@@ -74,7 +75,45 @@ namespace PasteApeart.Handler
             {
                 return;
             }
-            await ActionAsync(msg, types);
+            await ActionReturnResultAsync(msg, types);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="msg"></param>
+        /// <param name="methodName"></param>
+        /// <returns></returns>
+        public async Task<object> ActionResultAsync(string msg, string methodName = "HandleEventAsync")
+        {
+            if (string.IsNullOrWhiteSpace(msg))
+            {
+                return null;
+            }
+
+            if (_dtoTypeArray?.Any() != true)
+            {
+                _logger.LogError("ActionMessageAsync 的string模式下,构造函数的dtoTypes是必传的,表示EventModel所在程序集的类型集合");
+                return null;
+            }
+
+            return await ActionReturnResultAsync(msg, _dtoTypeArray, methodName);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="msg"></param>
+        /// <param name="types"></param>
+        /// <param name="methodName"></param>
+        /// <returns></returns>
+        public async Task<object> ActionResultAsync(string msg, Type[] types, string methodName = "HandleEventAsync")
+        {
+            if (string.IsNullOrWhiteSpace(msg))
+            {
+                return null;
+            }
+            return await ActionReturnResultAsync(msg, types, methodName);
         }
 
         /// <summary>
@@ -191,6 +230,132 @@ namespace PasteApeart.Handler
             }
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="msg"></param>
+        /// <param name="types"></param>
+        /// <param name="methodName"></param>
+        /// <returns></returns>
+        private async Task<object> ActionReturnResultAsync(string msg, Type[] types, string methodName = "HandleEventAsync")
+        {
+            object input = null;
+            object handler = null;
+            try
+            {
+                // 1. 只反序列化一次,使用 System.Text.Json 性能更好
+                using var jsonDoc = JsonDocument.Parse(msg);
+                var root = jsonDoc.RootElement;
+                JsonElement eventNameProperty;
+                // 使用不区分大小写的匹配,更健壮
+                if (!root.TryGetProperty("eventName", out eventNameProperty))
+                {
+                    root.TryGetProperty("EventName", out eventNameProperty);
+                }
+                // 获取字符串值并验证
+                string eventName = eventNameProperty.GetString();
+                if (string.IsNullOrEmpty(eventName))
+                {
+                    _logger.LogError($"EventName 字段值为空: {msg}");
+                    return null;
+                }
+                // 2. 获取事件类型(带缓存)
+                var modelType = _eventTypeCache.GetOrAdd(eventName, name =>
+                {
+                    return types.FirstOrDefault(x => x.Name == name);
+                });
+                if (modelType == null)
+                {
+                    _logger.LogError($"未找到事件类型: {eventName}");
+                    return null;
+                }
+                // 3. 反序列化为具体类型
+                input = JsonSerializer.Deserialize(msg, modelType, JsonConfig.Options);
+                if (input == null)
+                {
+                    _logger.LogError($"无法将消息反序列化为类型 {eventName}: {msg}");
+                    return null;
+                }
+                using var scope = _serviceProvider.CreateScope();
+                if (input is IEventModel tryModel)
+                {
+                    if (tryModel.ExpireSecond > 0)
+                    {
+                        await _channelHelper.WriteAutoQueueAsync(tryModel);
+                        return null;
+                    }
+                }
+                // 4. 获取处理器信息(带缓存)
+                var (handlerType, handleMethod) = _handlerCache.GetOrAdd(modelType, type =>
+                {
+                    var hType = typeof(IEventHandler<>).MakeGenericType(type);
+                    var method = hType.GetMethod(methodName);
+                    return (hType, method);
+                });
+                if (handleMethod == null)
+                {
+                    _logger.LogError($"处理器 {handlerType.Name} 没有 {methodName} 方法");
+                    return null;
+                }
+                handler = scope.ServiceProvider.GetRequiredService(handlerType);
+                if (handler == null)
+                {
+                    _logger.LogError($"没有找到 {eventName} 的 IEventHandler 实现");
+                    return null;
+                }
+                try
+                {
+                    // 5. 执行处理
+                    var task = handleMethod.Invoke(handler, new[] { input }) as Task;
+                    if (task != null)
+                    {
+                        await task;
+                        //var type = task.GetType();
+                        //if (type.IsGenericType)
+                        //{
+                        //    return type.GetProperty("Result")?.GetValue(task);
+                        //}
+                        //return null;
+                        // 从 handler 实例上读 Result 属性(而不是从 Task<T> 里读)
+                        var resultProp = handlerType.GetProperty("Result");
+                        return resultProp?.GetValue(handler);
+                    }
+                    else
+                    {
+                        _logger.LogError($"无法调用 {eventName} 的处理方法");
+                    }
+                }
+                catch (Exception handlerExl)
+                {
+                    _logger.LogException(handlerExl);
+                }
+                finally
+                {
+                    try
+                    {
+                        if (handler is IDisposable disposable)
+                        {
+                            disposable.Dispose();
+                        }
+                        if (handler is IAsyncDisposable disposable1)
+                        {
+                            await disposable1.DisposeAsync();
+                        }
+                    }
+                    catch (Exception exlDisposable)
+                    {
+                        _logger.LogException(exlDisposable);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                _logger.LogException(ex);
+            }
+            return null;
+        }
+
+
         private readonly ConcurrentDictionary<Type, Type> _eventHandlerCache = new();
         private readonly ConcurrentDictionary<Type, MethodInfo> _handleMethodCache = new();
 
framework/PasteApeart.Handler/common/IChannelHelper.cs
diff --git a/framework/PasteApeart.Handler/common/IChannelHelper.cs b/framework/PasteApeart.Handler/common/IChannelHelper.cs
index edcd0c6..c6cab3d 100644
--- a/framework/PasteApeart.Handler/common/IChannelHelper.cs
+++ b/framework/PasteApeart.Handler/common/IChannelHelper.cs
@@ -3,6 +3,9 @@ using System.Threading.Channels;
 
 namespace PasteApeart.Handler
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public interface IChannelHelper
     {
         /// <summary>
framework/PasteApeart.Handler/common/IEventActionHandler.cs
diff --git a/framework/PasteApeart.Handler/common/IEventActionHandler.cs b/framework/PasteApeart.Handler/common/IEventActionHandler.cs
index 4130c97..46da988 100644
--- a/framework/PasteApeart.Handler/common/IEventActionHandler.cs
+++ b/framework/PasteApeart.Handler/common/IEventActionHandler.cs
@@ -2,6 +2,9 @@ using PasteApeart.Application.Contracts;
 
 namespace PasteApeart.Handler
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public interface IEventActionHandler
     {
         /// <summary>
@@ -30,16 +33,33 @@ namespace PasteApeart.Handler
         /// <summary>
         /// 一般用于本地的Channel模式
         /// </summary>
-        /// <param name="read"></param>
+        /// <param name="msg"></param>
         /// <returns></returns>
         Task ActionMessageAsync(IEventModel msg);
 
         /// <summary>
         /// 
         /// </summary>
-        /// <param name="read"></param>
+        /// <param name="msg"></param>
         /// <returns></returns>
         [Obsolete("use ActionMessageAsync")]
         Task HanlderEventMessage(IEventModel msg);
+
+        /// <summary>
+        /// 有返回值的,自定义执行函数 一般用于事件控制台
+        /// </summary>
+        /// <param name="msg"></param>
+        /// <param name="methodName"></param>
+        /// <returns></returns>
+        Task<object> ActionResultAsync(string msg, string methodName = "HandleEventAsync");
+
+        /// <summary>
+        /// 有返回值的,自定义执行函数 一般用于事件控制台
+        /// </summary>
+        /// <param name="msg"></param>
+        /// <param name="types"></param>
+        /// <param name="methodName"></param>
+        /// <returns></returns>
+        Task<object> ActionResultAsync(string msg, Type[] types, string methodName = "HandleEventAsync");
     }
 }
\ No newline at end of file
framework/PasteApeart.Handler/common/ILevelHandler.cs
diff --git a/framework/PasteApeart.Handler/common/ILevelHandler.cs b/framework/PasteApeart.Handler/common/ILevelHandler.cs
index 07394d1..9da0d24 100644
--- a/framework/PasteApeart.Handler/common/ILevelHandler.cs
+++ b/framework/PasteApeart.Handler/common/ILevelHandler.cs
@@ -2,11 +2,44 @@ using PasteApeart.Domain.Entity;
 
 namespace PasteApeart.Handler.Level
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public interface ILevelHandler
     {
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="Tkey"></typeparam>
+        /// <param name="info"></param>
+        /// <returns></returns>
         Task AfterAddAsync<T, Tkey>(ILevelEntity<Tkey> info) where T : class, ILevelEntity<Tkey>;
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="Tkey"></typeparam>
+        /// <param name="info"></param>
+        /// <param name="oldFatherStr"></param>
+        /// <param name="oldLevel"></param>
+        /// <returns></returns>
         Task AfterUpdateAsync<T, Tkey>(ILevelEntity<Tkey> info, string oldFatherStr, int oldLevel) where T : class, ILevelEntity<Tkey>;
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="Tkey"></typeparam>
+        /// <param name="entities"></param>
         void AllResortByFatherIdAndSort<T, Tkey>(List<T> entities) where T : ILevelEntity<Tkey>;
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="Tkey"></typeparam>
+        /// <param name="TableName"></param>
+        /// <param name="input"></param>
+        /// <param name="step"></param>
+        /// <returns></returns>
         Task AutoSort<Tkey>(string TableName, ILevelEntity<Tkey> input, int step = 10);
     }
 }
\ No newline at end of file
framework/PasteApeart.Handler/common/LevelHandler.cs
diff --git a/framework/PasteApeart.Handler/common/LevelHandler.cs b/framework/PasteApeart.Handler/common/LevelHandler.cs
index 84c1d90..9bf163d 100644
--- a/framework/PasteApeart.Handler/common/LevelHandler.cs
+++ b/framework/PasteApeart.Handler/common/LevelHandler.cs
@@ -34,9 +34,10 @@ namespace PasteApeart.Handler.Level
 
 
         /// <summary>
-        /// 新增后调用,用于自动处理关系链
+        /// 
         /// </summary>
         /// <typeparam name="T"></typeparam>
+        /// <typeparam name="Tkey"></typeparam>
         /// <param name="info"></param>
         /// <returns></returns>
         public async Task AfterAddAsync<T, Tkey>(ILevelEntity<Tkey> info) where T : class, ILevelEntity<Tkey>
@@ -89,10 +90,12 @@ namespace PasteApeart.Handler.Level
         /// 
         /// </summary>
         /// <typeparam name="T"></typeparam>
+        /// <typeparam name="Tkey"></typeparam>
         /// <param name="info"></param>
         /// <param name="oldFatherStr"></param>
         /// <param name="oldLevel"></param>
         /// <returns></returns>
+        /// <exception cref="Exception"></exception>
         public async Task AfterUpdateAsync<T, Tkey>(ILevelEntity<Tkey> info, string oldFatherStr, int oldLevel) where T : class, ILevelEntity<Tkey>
         {
             //IQueryable<ILevelEntity> dbSet = null;
@@ -161,11 +164,12 @@ namespace PasteApeart.Handler.Level
 
 
         /// <summary>
-        /// 基于FatherId和Sort重新计算Level SortStr FatherStr
+        /// 
         /// </summary>
         /// <typeparam name="T"></typeparam>
+        /// <typeparam name="Tkey"></typeparam>
         /// <param name="entities"></param>
-        /// <returns></returns>
+        /// <exception cref="Exception"></exception>
         public void AllResortByFatherIdAndSort<T, Tkey>(List<T> entities) where T : ILevelEntity<Tkey>
         {
             if (entities == null || entities.Count == 0) return;
@@ -194,6 +198,7 @@ namespace PasteApeart.Handler.Level
         /// 
         /// </summary>
         /// <typeparam name="T"></typeparam>
+        /// <typeparam name="Tkey"></typeparam>
         /// <param name="node"></param>
         /// <param name="entities"></param>
         /// <exception cref="Exception"></exception>
framework/PasteApeart.Handler/extensions/ApeartExtensions.cs
diff --git a/framework/PasteApeart.Handler/extensions/ApeartExtensions.cs b/framework/PasteApeart.Handler/extensions/ApeartExtensions.cs
index 97ef783..d19c1af 100644
--- a/framework/PasteApeart.Handler/extensions/ApeartExtensions.cs
+++ b/framework/PasteApeart.Handler/extensions/ApeartExtensions.cs
@@ -90,41 +90,44 @@ namespace PasteApeart.Handler.Extensions
                 : source;
         }
 
-        //
-        // 摘要:
-        //     Used for paging. Can be used as an alternative to Skip(...).Take(...) chaining.
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="skipCount"></param>
+        /// <param name="maxResultCount"></param>
+        /// <returns></returns>
         public static IQueryable<T> PageBy<T>(this IQueryable<T> query, int skipCount, int maxResultCount)
         {
             Check.NotNull(query, "query");
             return query.Skip(skipCount).Take(maxResultCount);
         }
 
-        //
-        // 摘要:
-        //     Used for paging. Can be used as an alternative to Skip(...).Take(...) chaining.
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="TQueryable"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="skipCount"></param>
+        /// <param name="maxResultCount"></param>
+        /// <returns></returns>
         public static TQueryable PageBy<T, TQueryable>(this TQueryable query, int skipCount, int maxResultCount) where TQueryable : IQueryable<T>
         {
             Check.NotNull(query, "query");
             return (TQueryable)query.Skip(skipCount).Take(maxResultCount);
         }
 
-        //
-        // 摘要:
-        //     Filters a System.Linq.IQueryable`1 by given predicate if given condition is true.
-        //
-        //
-        // 参数:
-        //   query:
-        //     Queryable to apply filtering
-        //
-        //   condition:
-        //     A boolean value
-        //
-        //   predicate:
-        //     Predicate to filter the query
-        //
-        // 返回结果:
-        //     Filtered or not filtered query based on condition
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="condition"></param>
+        /// <param name="predicate"></param>
+        /// <returns></returns>
         public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
         {
             Check.NotNull(query, "query");
@@ -136,23 +139,15 @@ namespace PasteApeart.Handler.Extensions
             return query.Where(predicate);
         }
 
-        //
-        // 摘要:
-        //     Filters a System.Linq.IQueryable`1 by given predicate if given condition is true.
-        //
-        //
-        // 参数:
-        //   query:
-        //     Queryable to apply filtering
-        //
-        //   condition:
-        //     A boolean value
-        //
-        //   predicate:
-        //     Predicate to filter the query
-        //
-        // 返回结果:
-        //     Filtered or not filtered query based on condition
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="TQueryable"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="condition"></param>
+        /// <param name="predicate"></param>
+        /// <returns></returns>
         public static TQueryable WhereIf<T, TQueryable>(this TQueryable query, bool condition, Expression<Func<T, bool>> predicate) where TQueryable : IQueryable<T>
         {
             Check.NotNull(query, "query");
@@ -164,23 +159,14 @@ namespace PasteApeart.Handler.Extensions
             return (TQueryable)query.Where(predicate);
         }
 
-        //
-        // 摘要:
-        //     Filters a System.Linq.IQueryable`1 by given predicate if given condition is true.
-        //
-        //
-        // 参数:
-        //   query:
-        //     Queryable to apply filtering
-        //
-        //   condition:
-        //     A boolean value
-        //
-        //   predicate:
-        //     Predicate to filter the query
-        //
-        // 返回结果:
-        //     Filtered or not filtered query based on condition
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="condition"></param>
+        /// <param name="predicate"></param>
+        /// <returns></returns>
         public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, int, bool>> predicate)
         {
             Check.NotNull(query, "query");
@@ -192,23 +178,15 @@ namespace PasteApeart.Handler.Extensions
             return query.Where(predicate);
         }
 
-        //
-        // 摘要:
-        //     Filters a System.Linq.IQueryable`1 by given predicate if given condition is true.
-        //
-        //
-        // 参数:
-        //   query:
-        //     Queryable to apply filtering
-        //
-        //   condition:
-        //     A boolean value
-        //
-        //   predicate:
-        //     Predicate to filter the query
-        //
-        // 返回结果:
-        //     Filtered or not filtered query based on condition
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <typeparam name="TQueryable"></typeparam>
+        /// <param name="query"></param>
+        /// <param name="condition"></param>
+        /// <param name="predicate"></param>
+        /// <returns></returns>
         public static TQueryable WhereIf<T, TQueryable>(this TQueryable query, bool condition, Expression<Func<T, int, bool>> predicate) where TQueryable : IQueryable<T>
         {
             Check.NotNull(query, "query");
framework/PasteApeart.Handler/rabbit/IRabbitMQProducer.cs
diff --git a/framework/PasteApeart.Handler/rabbit/IRabbitMQProducer.cs b/framework/PasteApeart.Handler/rabbit/IRabbitMQProducer.cs
index e40b83d..e4b63a8 100644
--- a/framework/PasteApeart.Handler/rabbit/IRabbitMQProducer.cs
+++ b/framework/PasteApeart.Handler/rabbit/IRabbitMQProducer.cs
@@ -1,10 +1,32 @@
 namespace PasteApeart.Handler.rabbit
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public interface IRabbitMQProducer
     {
+        /// <summary>
+        /// 
+        /// </summary>
         void Close();
+        /// <summary>
+        /// 
+        /// </summary>
         void Dispose();
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="exchange"></param>
+        /// <param name="message"></param>
+        /// <param name="routingkey"></param>
+        /// <param name="maxRetries"></param>
+        /// <returns></returns>
         Task<bool> SendWithRetryAsync(string exchange, string message, string routingkey, int maxRetries = 3);
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="message"></param>
+        /// <returns></returns>
         Task WriteSubscribeAsync(string message);
     }
 }
\ No newline at end of file
framework/PasteApeart.Handler/rabbit/IRabbitMultiConsumerHandler.cs
diff --git a/framework/PasteApeart.Handler/rabbit/IRabbitMultiConsumerHandler.cs b/framework/PasteApeart.Handler/rabbit/IRabbitMultiConsumerHandler.cs
index 7b53e44..2dca042 100644
--- a/framework/PasteApeart.Handler/rabbit/IRabbitMultiConsumerHandler.cs
+++ b/framework/PasteApeart.Handler/rabbit/IRabbitMultiConsumerHandler.cs
@@ -1,9 +1,24 @@
 namespace PasteApeart.Handler.rabbit
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public interface IRabbitMultiConsumerHandler
     {
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns></returns>
         ValueTask DisposeAsync();
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns></returns>
         Task InitAsync();
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <returns></returns>
         Task ShutdownAsync();
     }
 }
\ No newline at end of file
framework/PasteApeart.Handler/rabbit/RabbitMQProducer.cs
diff --git a/framework/PasteApeart.Handler/rabbit/RabbitMQProducer.cs b/framework/PasteApeart.Handler/rabbit/RabbitMQProducer.cs
index 486d656..deb18c1 100644
--- a/framework/PasteApeart.Handler/rabbit/RabbitMQProducer.cs
+++ b/framework/PasteApeart.Handler/rabbit/RabbitMQProducer.cs
@@ -37,9 +37,10 @@ namespace PasteApeart.Handler.rabbit
         private readonly ILogger<RabbitMQProducer> _logger;
 
         /// <summary>
-        /// Constructor for RabbitMqClient
+        /// 
         /// </summary>
-        /// <param name="config">mandatory</param>
+        /// <param name="config"></param>
+        /// <param name="logger"></param>
         public RabbitMQProducer(IOptions<RabbitConfig> config, ILogger<RabbitMQProducer> logger)
         {
             _logger = logger;
framework/PasteApeart.Handler/redis/HashKeyValue.cs
diff --git a/framework/PasteApeart.Handler/redis/HashKeyValue.cs b/framework/PasteApeart.Handler/redis/HashKeyValue.cs
index 93beaee..0c3540d 100644
--- a/framework/PasteApeart.Handler/redis/HashKeyValue.cs
+++ b/framework/PasteApeart.Handler/redis/HashKeyValue.cs
@@ -1,8 +1,18 @@
 namespace PasteApeart.Handler.redis
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public class HashKeyValue
     {
+        /// <summary>
+        /// 
+        /// </summary>
         public string Key { get; set; }
+
+        /// <summary>
+        /// 
+        /// </summary>
         public string Value { get; set; }
     }
 }
framework/PasteApeart.Handler/redis/IAppCache.cs
diff --git a/framework/PasteApeart.Handler/redis/IAppCache.cs b/framework/PasteApeart.Handler/redis/IAppCache.cs
index 8942cb7..a58452b 100644
--- a/framework/PasteApeart.Handler/redis/IAppCache.cs
+++ b/framework/PasteApeart.Handler/redis/IAppCache.cs
@@ -139,7 +139,10 @@ namespace PasteApeart.Handler.redis
         /// 
         /// </summary>
         /// <param name="key"></param>
-        /// <param name="vals"></param>
+        /// <param name="field"></param>
+        /// <param name="value"></param>
+        /// <param name="isnum"></param>
+        /// <returns></returns>
         Task HashSetAsync(string key, string field, RedisValue value, bool isnum = false);
 
         /// <summary>
@@ -148,28 +151,29 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         string Print();
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="key"></param>
-        /// <param name="field"></param>
-        /// <param name="num"></param>
-        /// <returns></returns>
-        Task<long> HashIncrementAsync(string key, string field, long num = 1);
+        ///// <summary>
+        ///// 
+        ///// </summary>
+        ///// <param name="key"></param>
+        ///// <param name="field"></param>
+        ///// <param name="num"></param>
+        ///// <returns></returns>
+        //Task<long> HashIncrementAsync(string key, string field, long num = 1);
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="key"></param>
-        /// <param name="field"></param>
-        /// <returns></returns>
-        Task<long> HashDecrementAsync(string key, string field);
+        ///// <summary>
+        ///// 
+        ///// </summary>
+        ///// <param name="key"></param>
+        ///// <param name="field"></param>
+        ///// <returns></returns>
+        //Task<long> HashDecrementAsync(string key, string field);
 
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
+        /// <param name="isNum"></param>
         /// <returns></returns>
         Task<int> HashGetIntFieldAsync(string key, string field, bool isNum = false);
 
@@ -178,6 +182,7 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
+        /// <param name="isNum"></param>
         /// <returns></returns>
         Task<long> HashGetLongFieldAsync(string key, string field, bool isNum = false);
 
@@ -223,6 +228,7 @@ namespace PasteApeart.Handler.redis
         /// <param name="pattern"></param>
         /// <param name="page"></param>
         /// <param name="size"></param>
+        /// <param name="isincom"></param>
         /// <returns></returns>
         Task<List<HashEntry>> HashScanAsync(string key, string pattern, int page, int size, bool isincom = false);
 
@@ -231,6 +237,7 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="sunkey"></param>
+        /// <param name="isnum"></param>
         /// <returns></returns>
         Task<string> HashGetAsync(string key, string sunkey, bool isnum = false);
 
@@ -239,6 +246,7 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="fields"></param>
+        /// <param name="isinnum"></param>
         /// <returns></returns>
         Task<RedisValue[]> HashGetAsync(string key, RedisValue[] fields, bool isinnum = false);
 
@@ -292,7 +300,6 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
-        /// <param name="value"></param>
         /// <returns></returns>
         Task<bool> SortedSetRemoveAsync(string key, string field);
 
@@ -547,6 +554,21 @@ namespace PasteApeart.Handler.redis
         /// <param name="key"></param>
         /// <returns></returns>
         List<HashKeyValue> HashGetAll(string key);
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        HashEntry[] HashGetAllEntry(string key);
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        Task<HashEntry[]> HashGetAllEntryAsync(string key);
+
         ///// <summary>
         ///// 
         ///// </summary>
@@ -627,13 +649,13 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         string HashGet(string key, string sunkey);
 
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="key"></param>
-        /// <param name="sunkey"></param>
-        /// <returns></returns>
-        Task<string> HashGetAsync(string key, string sunkey);
+        ///// <summary>
+        ///// 
+        ///// </summary>
+        ///// <param name="key"></param>
+        ///// <param name="sunkey"></param>
+        ///// <returns></returns>
+        //Task<string> HashGetAsync(string key, string sunkey);
 
         /// <summary>
         /// 随机从Hash中获取一个
@@ -649,13 +671,13 @@ namespace PasteApeart.Handler.redis
 
 
 
-        /// <summary>
-        /// 添加某一个数据
-        /// </summary>
-        /// <param name="key"></param>
-        /// <param name="felid"></param>
-        /// <param name="num"></param>
-        Task HashIncrementAsync(string key, string felid, int num = 1);
+        ///// <summary>
+        ///// 添加某一个数据
+        ///// </summary>
+        ///// <param name="key"></param>
+        ///// <param name="felid"></param>
+        ///// <param name="num"></param>
+        //Task HashIncrementAsync(string key, string felid, int num = 1);
 
         /// <summary>
         /// 
framework/PasteApeart.Handler/redis/MemoryClient.bakup.cs
diff --git a/framework/PasteApeart.Handler/redis/MemoryClient.bakup.cs b/framework/PasteApeart.Handler/redis/MemoryClient.bakup.cs
new file mode 100644
index 0000000..c57bdf3
--- /dev/null
+++ b/framework/PasteApeart.Handler/redis/MemoryClient.bakup.cs
@@ -0,0 +1,1620 @@
+//using Microsoft.Extensions.Caching.Memory;
+//using StackExchange.Redis;
+//using System.Collections.Concurrent;
+//using System.Text;
+//using System.Text.Json;
+
+//namespace PasteApeart.Handler.redis
+//{
+//    /// <summary>
+//    /// 本地缓存
+//    /// </summary>
+//    public class MemoryClient : IAppCache
+//    {
+//        private readonly IMemoryCache _memoryCache;
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="memoryCache"></param>
+//        public MemoryClient(IMemoryCache memoryCache)
+//        {
+//            _memoryCache = memoryCache;
+//            key_hash_set = new ConcurrentDictionary<string, ConcurrentDictionary<string, string>>();
+//            key_hash_num = new ConcurrentDictionary<string, ConcurrentDictionary<string, long>>();
+//        }
+
+//        ///// <summary>
+//        ///// 
+//        ///// </summary>
+//        //private ConcurrentDictionary<string, string> key_val;
+
+//        ///// <summary>
+//        ///// 
+//        ///// </summary>
+//        //private ConcurrentDictionary<string, List<SortScore>> key_sort_set;
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        private ConcurrentDictionary<string, ConcurrentDictionary<string, string>> key_hash_set;
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        private ConcurrentDictionary<string, ConcurrentDictionary<string, long>> key_hash_num;
+
+//        public bool IsRedis { get => false; }
+
+//        public bool Delete(string key)
+//        {
+//            _memoryCache.Remove(key);
+//            return true;
+//        }
+
+//        /// <summary>
+//        /// error
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <returns></returns>
+//        public Task<bool> DeleteAsync(string key)
+//        {
+//            return Task.Run<bool>(() =>
+//            {
+//                return Delete(key);
+//            });
+//        }
+
+//        public bool Exists(string key)
+//        {
+//            return _memoryCache.TryGetValue(key, out var val);
+//            //throw new NotImplementedException();
+//        }
+
+//        public T GetObject<T>(string key)
+//        {
+//            if (_memoryCache.TryGetValue(key, out string val))
+//            {
+//                return JsonSerializer.Deserialize<T>(val, JsonConfig.Options);// JsonConvert.DeserializeObject<T>(val);
+//            }
+//            return default(T);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <returns></returns>
+//        public string Get(string key)
+//        {
+//            if (_memoryCache.TryGetValue(key, out string val))
+//            {
+//                return val;
+//            }
+//            return "";
+//            // throw new NotImplementedException();
+//        }
+
+//        public Task<T> GetObjectAsync<T>(string key)
+//        {
+//            return Task.Run<T>(() =>
+//            {
+//                return GetObject<T>(key);
+//            });
+//        }
+
+//        public Task<string> GetAsync(string key)
+//        {
+//            return Task.Run<string>(() =>
+//            {
+//                return Get(key);
+//            });
+//        }
+
+//        public string GetStringValue(string key)
+//        {
+//            return Get(key);
+//        }
+
+//        public string HashGet(string key, string sunkey)
+//        {
+//            throw new NotImplementedException();
+//        }
+
+//        public HashEntry[] HashGetAll(string key)
+//        {
+//            throw new NotImplementedException();
+//        }
+
+//        //public Task<HashEntry[]> HashGetAllAsync(string key)
+//        //{
+//        //    throw new NotImplementedException();
+//        //}
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="sunkey"></param>
+//        /// <returns></returns>
+//        public Task<string> HashGetAsync(string key, string sunkey, bool isnum = false)
+//        {
+//            if (key_hash_set.TryGetValue(key, out var val))
+//            {
+//                if (val != null && val != default)
+//                {
+//                    if (val.TryGetValue(sunkey, out var _val))
+//                    {
+//                        return Task.FromResult(_val);
+//                    }
+//                }
+//            }
+//            return Task.FromResult(String.Empty);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <returns></returns>
+//        public async Task<int> HashGetIntFieldAsync(string key, string field, bool isNum = false)
+//        {
+//            var read = await this.HashGetAsync(key, field, isNum);
+//            if (!string.IsNullOrEmpty(read))
+//            {
+//                int.TryParse(read, out var ival);
+//                return ival;
+//            }
+//            return default(int);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <returns></returns>
+//        public async Task<long> HashGetLongFieldAsync(string key, string field, bool isNum = false)
+//        {
+//            var read = await this.HashGetAsync(key, field, isNum);
+//            if (!string.IsNullOrEmpty(read))
+//            {
+//                long.TryParse(read, out var ival);
+//                return ival;
+//            }
+//            return default(long);
+//        }
+
+//        public void HashSet(string key, HashEntry[] vals)
+//        {
+//            throw new NotImplementedException();
+//        }
+
+//        //public void HashSetAsync(string key, HashEntry[] vals)
+//        //{
+//        //    throw new NotImplementedException();
+//        //}
+
+//        public bool Lock(string key, int seconds)
+//        {
+//            return false;
+//        }
+
+//        public Task<bool> LockAsync(string key, int seconds)
+//        {
+//            //return Task.Run<bool>(() =>
+//            //{
+//            //    return Lock(key, seconds);
+//            //});
+//            return Task.FromResult(true);
+//        }
+
+//        public bool Set(string key, string value, TimeSpan? expiry = null)
+//        {
+//            using (var wcache = _memoryCache.CreateEntry(key))
+//            {
+//                wcache.Value = value;
+//                if (expiry == null)
+//                {
+//                    wcache.AbsoluteExpiration = System.DateTimeOffset.Now.AddSeconds(30);
+//                }
+//                else
+//                {
+//                    wcache.AbsoluteExpiration = DateTimeOffset.Now.Add((TimeSpan)expiry);
+//                }
+//            }
+
+//            return true;
+//        }
+
+//        public bool Set(string key, string value, int seconds)
+//        {
+//            using (var wcache = _memoryCache.CreateEntry(key))
+//            {
+//                wcache.Value = value;
+
+//                wcache.AbsoluteExpiration = System.DateTimeOffset.Now.AddSeconds(seconds);
+
+//            }
+
+//            return true;
+//        }
+
+//        public bool Set(string key, string value)
+//        {
+//            using (var wcache = _memoryCache.CreateEntry(key))
+//            {
+//                wcache.Value = value;
+//            }
+//            return true;
+//        }
+
+//        public bool SetObject<T>(string key, T value, TimeSpan? expiry = null)
+//        {
+
+//            return Set(key, JsonSerializer.Serialize<T>(value, JsonConfig.Options), expiry);
+//        }
+
+//        public bool SetObject<T>(string key, T value, int seconds)
+//        {
+//            return Set(key, JsonSerializer.Serialize<T>(value, JsonConfig.Options), seconds);
+//        }
+
+//        public Task<bool> SetAsync(string key, string value, TimeSpan? expiry = null)
+//        {
+//            return Task.Run<bool>(() =>
+//            {
+//                return Set(key, value, expiry);
+//            });
+//        }
+
+//        public Task<bool> SetAsync(string key, string value, int seconds)
+//        {
+//            return Task.Run<bool>(() =>
+//            {
+//                return Set(key, value, seconds);
+//            });
+//        }
+
+//        public Task<bool> SetObjectAsync<T>(string key, T value, int second)
+//        {
+//            return Task.Run<bool>(() =>
+//            {
+//                return SetObject(key, value, second);
+//            });
+//        }
+
+//        public bool SetExpire(string key, TimeSpan? expiry)
+//        {
+//            if (_memoryCache.TryGetValue(key, out string sval))
+//            {
+
+//                return Set(key, sval, expiry);
+//            }
+//            return false;
+//        }
+
+//        public bool SetExpire(string key, int seconds)
+//        {
+//            if (_memoryCache.TryGetValue(key, out string sval))
+//            {
+//                return Set(key, sval, seconds);
+//            }
+//            return false;
+//        }
+
+//        public Task<bool> SetExpireAsync(string key, int seconds)
+//        {
+//            return Task.Run<bool>(() =>
+//            {
+//                return SetExpire(key, seconds);
+//            });
+//        }
+
+//        public Task<bool> SetExpireAsync(string key, TimeSpan? expiry)
+//        {
+//            return Task.Run<bool>(() =>
+//            {
+//                return SetExpire(key, expiry);
+//            });
+//        }
+
+//        public bool SetValue(string key, string val, int second)
+//        {
+//            return Set(key, val, second);
+//        }
+
+//        public bool SetValue(string key, string val)
+//        {
+//            return Set(key, val);
+//        }
+
+//        public bool UnLock(string key)
+//        {
+//            return false;
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <returns></returns>
+//        public Task<bool> UnLockAsync(string key)
+//        {
+//            //return Task.Run<bool>(() =>
+//            //{
+//            //    return UnLock(key);
+//            //});
+//            return Task.FromResult(true);
+//        }
+
+//        ///// <summary>
+//        ///// 
+//        ///// </summary>
+//        ///// <param name="key"></param>
+//        ///// <param name="vals"></param>
+//        ///// <returns></returns>
+//        //public async Task HashSetAsync(string key, HashEntry[] vals, bool isnum = false)
+//        //{
+//        //    await Task.Run(() =>
+//        //    {
+//        //        if (isnum)
+//        //        {
+//        //            if(key_hash_num.TryGetValue(key, out var _hash))
+//        //            {
+//        //                foreach (var entry in vals)
+//        //                {
+//        //                    _hash.AddOrUpdate(entry.Name.ToString(), long.Parse(entry.Value.ToString()), (k, oldValue) => long.Parse(entry.Value.ToString()));
+//        //                }
+//        //            }
+//        //            else
+//        //            {
+//        //                _hash = new ConcurrentDictionary<string, long>();
+
+//        //                foreach (var entry in vals)
+//        //                {
+//        //                    _hash.AddOrUpdate(entry.Name.ToString(), long.Parse(entry.Value.ToString()), (k, oldValue) => long.Parse(entry.Value.ToString()));
+//        //                }
+//        //                key_hash_num.TryAdd(key, _hash);
+//        //            }
+//        //        }
+//        //        else
+//        //        {
+//        //            key_hash_set.TryGetValue(key, out var _hash);
+//        //            if (_hash == null || _hash == default)
+//        //            {
+//        //                _hash = new ConcurrentDictionary<string, string>();
+//        //            }
+//        //            foreach (var entry in vals)
+//        //            {
+//        //                _hash.AddOrUpdate(entry.Name.ToString(), entry.Value.ToString(), (k, oldValue) => entry.Value.ToString());
+//        //            }
+//        //            key_hash_set.AddOrUpdate(key, _hash, (k, oldvalue) => _hash);
+//        //        }
+
+
+//        //    });
+//        //}
+
+//        //public List<HashKeyValue> HashGetAll(string key)
+//        //{
+//        //    throw new NotImplementedException();
+//        //}
+
+//        //public Task<List<HashKeyValue>> HashGetAllAsync(string key)
+//        //{
+//        //    throw new NotImplementedException();
+//        //}
+
+//        public void HashSet(string key, List<HashKeyValue> vals)
+//        {
+//            throw new NotImplementedException();
+//        }
+
+//        ///// <summary>
+//        ///// 
+//        ///// </summary>
+//        ///// <param name="key"></param>
+//        ///// <param name="vals"></param>
+//        ///// <returns></returns>
+//        //public async Task HashSetAsync(string key, List<HashKeyValue> vals, bool isnum = false)
+//        //{
+//        //    await Task.Run(() =>
+//        //    {
+//        //        if (isnum)
+//        //        {
+//        //            if(key_hash_num.TryGetValue(key, out var _hash))
+//        //            {
+//        //                foreach (var entry in vals)
+//        //                {
+//        //                    _hash.AddOrUpdate(entry.Key, long.Parse(entry.Value), (k, oldValue) => long.Parse(entry.Value));
+//        //                }
+//        //            }
+//        //            else
+//        //            {
+//        //                _hash = new ConcurrentDictionary<string, long>();
+//        //                foreach (var entry in vals)
+//        //                {
+//        //                    _hash.AddOrUpdate(entry.Key, long.Parse(entry.Value), (k, oldValue) => long.Parse(entry.Value));
+//        //                }
+//        //                key_hash_num.TryAdd(key, _hash);
+//        //            }
+//        //        }
+//        //        else
+//        //        {
+//        //            key_hash_set.TryGetValue(key, out var _hash);
+//        //            if (_hash == null || _hash == default)
+//        //            {
+//        //                _hash = new ConcurrentDictionary<string, string>();
+//        //            }
+//        //            foreach (var entry in vals)
+//        //            {
+//        //                _hash.AddOrUpdate(entry.Key, entry.Value, (k, oldValue) => entry.Value);
+//        //            }
+//        //            key_hash_set.AddOrUpdate(key, _hash, (k, oldvalue) => _hash);
+//        //        }
+//        //    });
+//        //}
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <param name="num"></param>
+//        /// <returns></returns>
+//        public Task<long> HashIncrementAsync(string key, string field, long num = 1)
+//        {
+//            var _result = num;
+//            key_hash_num.TryGetValue(key, out var _hash);
+//            if (_hash == null || _hash == default)
+//            {
+//                _hash = new ConcurrentDictionary<string, long>() { };
+//                _hash.TryAdd(field, num);
+//                key_hash_num.TryAdd(key, _hash);
+//            }
+//            else
+//            {
+//                if (_hash.ContainsKey(field))
+//                {
+//                    _hash[field] = _hash[field] + num;
+//                    _result = _hash[field];
+//                }
+//                else
+//                {
+//                    _hash.TryAdd(field, num);
+//                }
+//            }
+//            return Task.FromResult(_result);
+//        }
+
+//        ///// <summary>
+//        ///// 
+//        ///// </summary>
+//        ///// <param name="key"></param>
+//        ///// <param name="start"></param>
+//        ///// <param name="stop"></param>
+//        ///// <returns></returns>
+//        //public Task<SortedSetEntry[]> SortedSetRangeByRankWithScoresAsync(string key, int start = 0, int stop = 1)
+//        //{
+//        //    if (key_hash_num.TryGetValue(key, out var _hash))
+//        //    {
+//        //        var list = new List<SortedSetEntry>();
+//        //        var hits = _hash.Where(x => x.Value >= start && x.Value < stop).ToList();
+//        //        foreach (var item in hits)
+//        //        {
+//        //            list.Add(new SortedSetEntry(item.Key, item.Value));
+//        //        }
+//        //        return Task.FromResult(list.ToArray());
+//        //    }
+//        //    return Task.FromResult(new SortedSetEntry[] { });
+//        //}
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="start"></param>
+//        /// <param name="stop"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<RedisValue[]> SortedSetRangeByScoreAsync(string key, long start = 0, long stop = 1)
+//        {
+//            if (key_hash_num.TryGetValue(key, out var _hash))
+//            {
+//                var list = new List<RedisValue>();
+//                var hits = _hash
+//                    .PasteWhereIf(start < stop, x => start <= x.Value && x.Value < stop)
+//                    .PasteWhereIf(start > stop, x => stop <= x.Value && x.Value < start)
+//                    .ToList();
+//                foreach (var item in hits)
+//                {
+//                    list.Add(new RedisValue(item.Key));
+//                }
+//                return Task.FromResult(list.ToArray());
+//            }
+//            return Task.FromResult(new RedisValue[] { });
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <param name="num"></param>
+//        /// <returns></returns>
+//        public Task<long> SortedSetIncrementAsync(string key, string field, long num = 1)
+//        {
+//            var _result = num;
+//            key_hash_num.TryGetValue(key, out var _hash);
+//            if (_hash == null || _hash == default)
+//            {
+//                _hash = new ConcurrentDictionary<string, long>() { };
+//                _hash.TryAdd(field, num);
+//                key_hash_num.TryAdd(key, _hash);
+//            }
+//            else
+//            {
+//                if (_hash.ContainsKey(field))
+//                {
+//                    _hash[field] = _hash[field] + num;
+//                    _result = _hash[field];
+//                }
+//                else
+//                {
+//                    _hash.TryAdd(field, num);
+//                }
+//            }
+//            return Task.FromResult(_result);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <param name="num"></param>
+//        /// <returns></returns>
+//        public Task<long> SortedSetDecrementAsync(string key, string field, long num)
+//        {
+//            var _result = num;
+//            key_hash_num.TryGetValue(key, out var _hash);
+//            if (_hash == null || _hash == default)
+//            {
+//                _hash = new ConcurrentDictionary<string, long>() { };
+//                _hash.TryAdd(field, num);
+//                key_hash_num.TryAdd(key, _hash);
+//            }
+//            else
+//            {
+//                if (_hash.ContainsKey(field))
+//                {
+//                    _hash[field] = _hash[field] - num;
+//                    _result = _hash[field];
+//                }
+//                else
+//                {
+//                    _hash.TryAdd(field, num);
+//                }
+//            }
+//            return Task.FromResult(_result);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <returns></returns>
+//        public Task<bool> SortedSetRemoveAsync(string key, string field)
+//        {
+//            var _result = false;
+//            if (key_hash_num.TryGetValue(key, out var _hash))
+//            {
+//                if (_hash.ContainsKey(field))
+//                {
+//                    _hash.Remove(field, out _);
+//                    _result = true;
+//                }
+//            }
+//            return Task.FromResult(_result);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <param name="num"></param>
+//        /// <returns></returns>
+//        public Task<bool> SortedSetAddAsync(string key, string field, long num)
+//        {
+//            if (key_hash_num.TryGetValue(key, out var _hash))
+//            {
+//                if (_hash.ContainsKey(field))
+//                {
+//                    _hash[field] = num;
+//                }
+//                else
+//                {
+//                    _hash.TryAdd(field, num);
+//                }
+//            }
+//            else
+//            {
+//                _hash = new ConcurrentDictionary<string, long>() { };
+//                _hash.TryAdd(field, num);
+//                key_hash_num.TryAdd(key, _hash);
+//            }
+//            return Task.FromResult(true);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<bool> ExistsAsync(string key)
+//        {
+//            var _result = _memoryCache.TryGetValue(key, out var val);
+//            return Task.FromResult(_result);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<List<HashKeyValue>> HashGetAllAsync(string key)
+//        {
+//            if (key_hash_set.TryGetValue(key, out var _hash))
+//            {
+//                var finds = new List<HashKeyValue>();
+//                foreach (var item in _hash)
+//                {
+//                    finds.Add(new HashKeyValue { Key = item.Key, Value = item.Value });
+//                }
+//                return Task.FromResult(finds);
+//            }
+//            if (key_hash_num.TryGetValue(key, out var _hash_num))
+//            {
+//                var finds = new List<HashKeyValue>();
+//                foreach (var item in _hash_num)
+//                {
+//                    finds.Add(new HashKeyValue { Key = item.Key, Value = item.ToString() });
+//                }
+//                return Task.FromResult(finds);
+//            }
+//            return Task.FromResult(new List<HashKeyValue> { });
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <returns></returns>
+//        public Task<long> HashDecrementAsync(string key, string field)
+//        {
+//            var num = 1;
+//            long _result = num;
+//            key_hash_num.TryGetValue(key, out var _hash);
+//            if (_hash == null || _hash == default)
+//            {
+//                _hash = new ConcurrentDictionary<string, long>() { };
+//                _hash.TryAdd(field, 0 - num);
+//                key_hash_num.TryAdd(key, _hash);
+//            }
+//            else
+//            {
+//                if (_hash.ContainsKey(field))
+//                {
+//                    _hash[field] = _hash[field] - num;
+//                    _result = _hash[field];
+//                }
+//                else
+//                {
+//                    _hash.TryAdd(field, num);
+//                }
+//            }
+//            return Task.FromResult(_result);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="filed"></param>
+//        /// <returns></returns>
+//        public Task<bool> HashExistsAsync(string key, string filed)
+//        {
+//            var _result = false;
+
+//            if (key_hash_num.TryGetValue(key, out var _hash))
+//            {
+//                if (_hash.ContainsKey(filed))
+//                {
+//                    _result = true;
+//                }
+//            }
+//            if (!_result)
+//            {
+//                if (key_hash_set.TryGetValue(key, out var hash_key))
+//                {
+//                    if (hash_key.ContainsKey(filed))
+//                    {
+//                        _result = true;
+//                    }
+//                }
+//            }
+//            return Task.FromResult(true);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <param name="value"></param>
+//        /// <returns></returns>
+//        public async Task HashSetAsync(string key, string field, RedisValue value, bool isnum = false)
+//        {
+//            await Task.Run(() =>
+//            {
+//                if (isnum)
+//                {
+//                    if (key_hash_num.TryGetValue(key, out var hash_key))
+//                    {
+//                        hash_key.AddOrUpdate(field, long.Parse(value.ToString()), (n, o) => long.Parse(value.ToString()));
+//                    }
+//                    else
+//                    {
+//                        var find = new ConcurrentDictionary<string, long>();
+//                        find.TryAdd(field, long.Parse(value.ToString()));
+//                        key_hash_num.TryAdd(key, find);
+//                    }
+//                }
+//                else
+//                {
+//                    if (key_hash_set.TryGetValue(key, out var hash_key))
+//                    {
+//                        hash_key.AddOrUpdate(field, value.ToString(), (n, o) => value.ToString());
+//                    }
+//                    else
+//                    {
+//                        var find = new ConcurrentDictionary<string, string>();
+//                        find.TryAdd(field, value.ToString());
+//                        key_hash_set.TryAdd(key, find);
+//                    }
+//                }
+//            });
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <typeparam name="T"></typeparam>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <returns></returns>
+//        public Task<T> HashGetObjectAsync<T>(string key, string field)
+//        {
+//            if (key_hash_set.TryGetValue(key, out var hash_key))
+//            {
+//                if (hash_key.TryGetValue(field, out var _value))
+//                {
+//                    if (!String.IsNullOrEmpty(_value))
+//                    {
+//                        var t = JsonSerializer.Deserialize<T>(_value, JsonConfig.Options);// Newtonsoft.Json.JsonConvert.DeserializeObject<T>(_value);
+//                        return Task.FromResult(t);
+//                    }
+//                }
+//            }
+//            return Task.FromResult(default(T));
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <typeparam name="T"></typeparam>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <param name="entity"></param>
+//        /// <returns></returns>
+//        public Task<bool> HashSetObjectAsync<T>(string key, string field, T entity)
+//        {
+//            var value = JsonSerializer.Serialize<T>(entity, JsonConfig.Options);
+//            //Newtonsoft.Json.JsonConvert.SerializeObject(entity);
+//            if (key_hash_set.TryGetValue(key, out var hash_key))
+//            {
+
+//                hash_key.AddOrUpdate(field, value, (n, o) => value);
+
+//            }
+//            else
+//            {
+//                var find = new ConcurrentDictionary<string, string>();
+//                find.TryAdd(field, value);
+//                key_hash_set.TryAdd(key, find);
+//            }
+//            return Task.FromResult(true);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="pattern"></param>
+//        /// <param name="page"></param>
+//        /// <param name="size"></param>
+//        /// <returns></returns>
+//        public Task<List<HashEntry>> HashScanAsync(string key, string pattern, int page, int size, bool isincom = false)
+//        {
+//            if (isincom)
+//            {
+//                if (key_hash_num.TryGetValue(key, out var hash_key))
+//                {
+//                    var position = 3;//1left 2right 3like
+//                    if (pattern.StartsWith("*"))
+//                    {
+//                        position = 1;
+//                    }
+//                    if (pattern.EndsWith("*"))
+//                    {
+//                        if (position == 1)
+//                        {
+//                            position = 3;
+//                        }
+//                        else
+//                        {
+//                            position = 2;
+//                        }
+//                    }
+//                    pattern = pattern.Replace("*", "");
+//                    var vals = hash_key
+//                        .PasteWhereIf(position == 1, x => x.Key.EndsWith(pattern))
+//                        .PasteWhereIf(position == 2, x => x.Key.StartsWith(pattern))
+//                        .PasteWhereIf(position == 3, x => x.Key.Contains(pattern))
+//                        .OrderBy(x => x.Key)
+//                        .ToList();
+//                    var start = (page - 1) * size;
+//                    var end = page * size;
+//                    var list = new List<HashEntry>();
+//                    for (var k = 0; k < vals.Count; k++)
+//                    {
+//                        if (k >= start && k < end)
+//                        {
+//                            var item = vals[k];
+//                            list.Add(new HashEntry(item.Key, item.Value));
+//                        }
+//                        if (k > end)
+//                        {
+//                            break;
+//                        }
+//                    }
+//                    return Task.FromResult(list);
+//                }
+//            }
+//            else
+//            {
+//                if (key_hash_set.TryGetValue(key, out var hash_key))
+//                {
+//                    var position = 3;//1left 2right 3like
+//                    if (pattern.StartsWith("*"))
+//                    {
+//                        position = 1;
+//                    }
+//                    if (pattern.EndsWith("*"))
+//                    {
+//                        if (position == 1)
+//                        {
+//                            position = 3;
+//                        }
+//                        else
+//                        {
+//                            position = 2;
+//                        }
+//                    }
+//                    pattern = pattern.Replace("*", "");
+//                    var vals = hash_key
+//                        .PasteWhereIf(position == 1, x => x.Key.StartsWith(pattern))
+//                        .PasteWhereIf(position == 2, x => x.Key.EndsWith(pattern))
+//                        .PasteWhereIf(position == 3, x => x.Key.Contains(pattern))
+//                        .OrderBy(x => x.Key)
+//                        .ToList();
+//                    var start = (page - 1) * size;
+//                    var end = page * size;
+//                    var list = new List<HashEntry>();
+//                    for (var k = 0; k < vals.Count; k++)
+//                    {
+//                        if (k >= start && k < end)
+//                        {
+//                            var item = vals[k];
+//                            list.Add(new HashEntry(item.Key, item.Value));
+//                        }
+//                        if (k > end)
+//                        {
+//                            break;
+//                        }
+//                    }
+//                    return Task.FromResult(list);
+//                }
+//            }
+//            return Task.FromResult(new List<HashEntry> { });
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="fields"></param>
+//        /// <returns></returns>
+//        public Task<RedisValue[]> HashGetAsync(string key, RedisValue[] fields, bool isnum = false)
+//        {
+//            var fis = fields.Select(x => x.ToString()).ToArray();
+//            if (!isnum)
+//            {
+//                if (key_hash_set.TryGetValue(key, out var hash_key))
+//                {
+//                    var haves = hash_key.Where(x => fis.Contains(x.Key)).ToList();
+//                    var reds = new List<RedisValue>();
+//                    foreach (var kv in haves)
+//                    {
+//                        reds.Add(kv.Value);
+//                    }
+//                    return Task.FromResult(reds.ToArray());
+//                }
+//            }
+//            else
+//            {
+//                if (key_hash_num.TryGetValue(key, out var hash_key))
+//                {
+//                    var haves = hash_key.Where(x => fis.Contains(x.Key)).ToList();
+//                    var reds = new List<RedisValue>();
+//                    foreach (var kv in haves)
+//                    {
+//                        reds.Add(kv.Value);
+//                    }
+//                    return Task.FromResult(reds.ToArray());
+//                }
+//            }
+//            return Task.FromResult(new RedisValue[] { });
+//        }
+
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="field"></param>
+//        /// <returns></returns>
+//        public async Task<bool> HashDeleteAsync(string key, string field)
+//        {
+//            await Task.Run(() =>
+//            {
+//                var _result = false;
+//                if (key_hash_set.TryGetValue(key, out var hash_key))
+//                {
+//                    if (hash_key.ContainsKey(field))
+//                    {
+//                        _result = true;
+//                    }
+//                    hash_key.Remove(field, out var abc);
+//                }
+//                if (!_result)
+//                {
+//                    if (key_hash_num.TryGetValue(key, out var _hash))
+//                    {
+//                        if (_hash.ContainsKey(field))
+//                        {
+//                            _result = true;
+//                        }
+//                        _hash.Remove(field, out var abc);
+//                    }
+//                }
+//                return _result;
+//            });
+//            return false;
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="fields"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<bool> HashDeleteAsync(string key, RedisValue[] fields)
+//        {
+//            var fis = fields.Select(x => x.ToString()).ToArray();
+//            if (key_hash_set.TryGetValue(key, out var hash_key))
+//            {
+//                foreach (var kv in fis)
+//                {
+//                    hash_key.Remove(kv, out var va);
+//                }
+//                var haves = hash_key.Where(x => fis.Contains(x.Key)).ToList();
+//                var reds = new List<RedisValue>();
+//                foreach (var kv in haves)
+//                {
+//                    reds.Add(kv.Value);
+//                }
+//                return Task.FromResult(true);
+//            }
+//            return Task.FromResult(false);
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<long> HashLengthAsync(string key)
+//        {
+//            if (key_hash_set.TryGetValue(key, out var hash_key))
+//            {
+//                return Task.FromResult((long)hash_key.Keys.Count);
+//            }
+//            return Task.FromResult((long)0);
+//        }
+
+//        /// <summary>
+//        /// 打印
+//        /// </summary>
+//        /// <returns></returns>
+//        public string Print()
+//        {
+//            var sb = new StringBuilder();
+
+//            if (key_hash_set != null && key_hash_set.Any())
+//            {
+//                //sb.AppendLine(Newtonsoft.Json.JsonConvert.SerializeObject(key_hash_set));
+//                sb.AppendLine(JsonSerializer.Serialize(key_hash_set, JsonConfig.Options));
+//            }
+
+//            if (key_hash_num != null && key_hash_num.Any())
+//            {
+//                //sb.AppendLine(Newtonsoft.Json.JsonConvert.SerializeObject(key_hash_num));
+//                sb.AppendLine(JsonSerializer.Serialize(key_hash_set, JsonConfig.Options));
+//            }
+
+//            return sb.ToString();
+//        }
+
+
+//        //------------------------------------------------
+
+
+//        //private readonly IMemoryCache _memoryCache;
+//        private static readonly Random _random = new();
+
+//        //public MemoryClient(IMemoryCache memoryCache)
+//        //{
+//        //    _memoryCache = memoryCache;
+//        //}
+
+//        //public bool IsRedis => false;
+
+//        #region 同步方法
+
+//        //public bool Delete(string key)
+//        //{
+//        //    _memoryCache.Remove(key);
+//        //    return true;
+//        //}
+
+//        //public bool Exists(string key)
+//        //{
+//        //    return _memoryCache.TryGetValue(key, out _);
+//        //}
+
+//        //public string Get(string key)
+//        //{
+//        //    return _memoryCache.TryGetValue(key, out string? val) ? val ?? string.Empty : string.Empty;
+//        //}
+
+//        //public T GetObject<T>(string key)
+//        //{
+//        //    if (_memoryCache.TryGetValue(key, out string? val) && !string.IsNullOrEmpty(val))
+//        //    {
+//        //        return JsonConvert.DeserializeObject<T>(val);
+//        //    }
+//        //    return default;
+//        //}
+
+//        //public string GetStringValue(string key)
+//        //{
+//        //    return Get(key);
+//        //}
+
+//        public object TryGetValue(string key)
+//        {
+//            return _memoryCache.TryGetValue(key, out var val) ? val : null;
+//        }
+
+//        public T GetOrCreate<T>(string key, Func<ICacheEntry, T> factory, TimeSpan? expiration = null)
+//        {
+//            return _memoryCache.GetOrCreate(key, entry =>
+//            {
+//                SetCacheEntryOptions(entry, expiration);
+//                return factory(entry);
+//            });
+//        }
+
+//        //public bool Set(string key, string value, TimeSpan? expiry = null)
+//        //{
+//        //    using var entry = _memoryCache.CreateEntry(key);
+//        //    entry.Value = value;
+//        //    SetCacheEntryOptions(entry, expiry);
+//        //    return true;
+//        //}
+
+//        //public bool Set(string key, string value, int seconds)
+//        //{
+//        //    return Set(key, value, TimeSpan.FromSeconds(seconds));
+//        //}
+
+//        //public bool Set(string key, string value)
+//        //{
+//        //    using var entry = _memoryCache.CreateEntry(key);
+//        //    entry.Value = value;
+//        //    return true;
+//        //}
+
+//        //public bool SetObject<T>(string key, T value, TimeSpan? expiry = null)
+//        //{
+//        //    return Set(key, JsonConvert.SerializeObject(value), expiry);
+//        //}
+
+//        //public bool SetObject<T>(string key, T value, int seconds)
+//        //{
+//        //    return Set(key, JsonConvert.SerializeObject(value), TimeSpan.FromSeconds(seconds));
+//        //}
+
+//        public bool CreateEntry(string key, object value, TimeSpan? expiry = null)
+//        {
+//            using var entry = _memoryCache.CreateEntry(key);
+//            entry.Value = value;
+//            SetCacheEntryOptions(entry, expiry);
+//            return true;
+//        }
+
+//        //public bool SetValue(string key, string val, int second)
+//        //{
+//        //    return Set(key, val, second);
+//        //}
+
+//        //public bool SetValue(string key, string val)
+//        //{
+//        //    return Set(key, val);
+//        //}
+
+//        //public bool SetExpire(string key, TimeSpan? expiry)
+//        //{
+//        //    if (_memoryCache.TryGetValue(key, out string? val))
+//        //    {
+//        //        return Set(key, val ?? string.Empty, expiry);
+//        //    }
+//        //    return false;
+//        //}
+
+//        //public bool SetExpire(string key, int seconds)
+//        //{
+//        //    return SetExpire(key, TimeSpan.FromSeconds(seconds));
+//        //}
+
+//        //public bool Lock(string key, int seconds)
+//        //{
+//        //    // MemoryCache 不支持分布式锁,直接返回 true
+//        //    return true;
+//        //}
+
+//        //public bool UnLock(string key)
+//        //{
+//        //    return true;
+//        //}
+
+//        #endregion
+
+//        #region 异步方法(同步包装,返回 Task)
+
+//        //public Task<bool> DeleteAsync(string key)
+//        //{
+//        //    Delete(key);
+//        //    return Task.FromResult(true);
+//        //}
+
+//        public Task BatchRemoveAsync(string[] keys)
+//        {
+//            if (keys != null)
+//            {
+//                foreach (var key in keys)
+//                {
+//                    if (!string.IsNullOrEmpty(key))
+//                    {
+//                        _memoryCache.Remove(key);
+//                    }
+//                }
+//            }
+//            return Task.CompletedTask;
+//        }
+
+//        //public Task<bool> ExistsAsync(string key)
+//        //{
+//        //    return Task.FromResult(Exists(key));
+//        //}
+
+//        //public Task<string> GetAsync(string key)
+//        //{
+//        //    return Task.FromResult(Get(key));
+//        //}
+
+//        //public Task<T?> GetObjectAsync<T>(string key)
+//        //{
+//        //    return Task.FromResult(GetObject<T>(key));
+//        //}
+
+//        public Task<T> GetOrCreateAsync<T>(string key, Func<ICacheEntry, Task<T>> factory, TimeSpan? expiration = null)
+//        {
+//            return _memoryCache.GetOrCreateAsync(key, async entry =>
+//            {
+//                SetCacheEntryOptions(entry, expiration);
+//                return await factory(entry);
+//            });
+//        }
+
+//        //public Task<bool> SetAsync(string key, string value, TimeSpan? expiry = null)
+//        //{
+//        //    return Task.FromResult(Set(key, value, expiry));
+//        //}
+
+//        //public Task<bool> SetAsync(string key, string value, int seconds)
+//        //{
+//        //    return Task.FromResult(Set(key, value, seconds));
+//        //}
+
+//        //public Task<bool> SetObjectAsync<T>(string key, T value, int second)
+//        //{
+//        //    return Task.FromResult(SetObject(key, value, second));
+//        //}
+
+//        //public Task<bool> SetExpireAsync(string key, int seconds)
+//        //{
+//        //    return Task.FromResult(SetExpire(key, seconds));
+//        //}
+
+//        //public Task<bool> SetExpireAsync(string key, TimeSpan? expiry)
+//        //{
+//        //    return Task.FromResult(SetExpire(key, expiry));
+//        //}
+
+//        //public Task<bool> LockAsync(string key, int seconds)
+//        //{
+//        //    return Task.FromResult(Lock(key, seconds));
+//        //}
+
+//        //public Task<bool> UnLockAsync(string key)
+//        //{
+//        //    return Task.FromResult(UnLock(key));
+//        //}
+
+//        #endregion
+
+//        #region Hash 操作
+
+//        //public string HashGet(string key, string subKey)
+//        //{
+//        //    if (_memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> dict)
+//        //    {
+//        //        return dict.TryGetValue(subKey, out var val) ? val : string.Empty;
+//        //    }
+//        //    return string.Empty;
+//        //}
+
+//        //public HashEntry[] HashGetAll(string key)
+//        //{
+//        //    if (_memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> dict)
+//        //    {
+//        //        return dict.Select(x => new HashEntry(x.Key, x.Value)).ToArray();
+//        //    }
+//        //    return Array.Empty<HashEntry>();
+//        //}
+
+//        //public void HashSet(string key, HashEntry[] vals)
+//        //{
+//        //    var dict = _memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> existing
+//        //        ? existing
+//        //        : new Dictionary<string, string>();
+
+//        //    foreach (var entry in vals)
+//        //    {
+//        //        dict[entry.Name.ToString()] = entry.Value.ToString();
+//        //    }
+
+//        //    _memoryCache.Set(key, dict);
+//        //}
+
+//        public Task<string> HashGetAsync(string key, string subKey)
+//        {
+//            return Task.FromResult(HashGet(key, subKey));
+//        }
+
+//        //public Task<HashEntry[]> HashGetAllAsync(string key)
+//        //{
+//        //    return Task.FromResult(HashGetAll(key));
+//        //}
+
+//        public Task HashSetAsync(string key, HashEntry[] vals)
+//        {
+//            HashSet(key, vals);
+//            return Task.CompletedTask;
+//        }
+
+//        ///// <summary>
+//        ///// 
+//        ///// </summary>
+//        ///// <param name="key"></param>
+//        ///// <param name="field"></param>
+//        ///// <returns></returns>
+//        //public Task<bool> HashDeleteAsync(string key, string field)
+//        //{
+//        //    if (_memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> dict)
+//        //    {
+//        //        if (dict.ContainsKey(field))
+//        //        {
+//        //            dict.Remove(field);
+//        //        }
+//        //    }
+//        //    return Task.FromResult(true);
+//        //}
+
+//        public Task<HashEntry> HashRandomFieldsWithValuesAsync(string key)
+//        {
+//            if (_memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> dict && dict.Count > 0)
+//            {
+//                var keys = dict.Keys.ToArray();
+//                var randomKey = keys[_random.Next(keys.Length)];
+//                return Task.FromResult(new HashEntry(randomKey, dict[randomKey]));
+//            }
+//            return Task.FromResult(new HashEntry(string.Empty, string.Empty));
+//        }
+
+//        public Task<long> HashIncrementAsync(string key, RedisValue field, long num = 1)
+//        {
+//            // MemoryCache 不支持原子增减,简单实现
+//            var current = HashGet(key, field.ToString());
+//            if (long.TryParse(current, out var value))
+//            {
+//                var newValue = value + num;
+//                HashSet(key, new[] { new HashEntry(field, newValue.ToString()) });
+//                return Task.FromResult(newValue);
+//            }
+//            HashSet(key, new[] { new HashEntry(field, num.ToString()) });
+//            return Task.FromResult(num);
+//        }
+
+//        public Task<long> HashDecrementAsync(string key, RedisValue field, long num = 1)
+//        {
+//            return HashIncrementAsync(key, field, -num);
+//        }
+
+//        #endregion
+
+//        #region 未实现的方法(抛出明确异常)
+
+//        //public void HashSet(string key, List<HashKeyValue> vals)
+//        //{
+//        //    throw new NotImplementedException("MemoryCache 不支持此操作");
+//        //}
+
+//        public Task HashSetAsync(string key, List<HashKeyValue> vals)
+//        {
+//            throw new NotImplementedException("MemoryCache 不支持此操作");
+//        }
+
+//        List<HashKeyValue> IAppCache.HashGetAll(string key)
+//        {
+//            throw new NotImplementedException("MemoryCache 不支持此操作");
+//        }
+
+//        Task<List<HashKeyValue>> IAppCache.HashGetAllAsync(string key)
+//        {
+//            throw new NotImplementedException("MemoryCache 不支持此操作");
+//        }
+
+//        public Task<HashEntry[]> HashScanAsync(string key, string pattern, int size = 1, int cursor = 0, int offset = 0)
+//        {
+//            throw new NotImplementedException("MemoryCache 不支持 HashScan");
+//        }
+
+//        #endregion
+
+//        #region 私有辅助方法
+
+//        private static void SetCacheEntryOptions(ICacheEntry entry, TimeSpan? expiration)
+//        {
+//            if (expiration.HasValue)
+//            {
+//                entry.AbsoluteExpirationRelativeToNow = expiration;
+//            }
+//            else
+//            {
+//                entry.SlidingExpiration = TimeSpan.FromMinutes(5);
+//            }
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <param name="felid"></param>
+//        /// <param name="num"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task HashIncrementAsync(string key, string felid, int num = 1)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="key"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<string> ReadStringAsync(string key)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <typeparam name="T"></typeparam>
+//        /// <param name="key"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<T> ReadObjectAsync<T>(string key)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <param name="val"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<bool> SetAddAsync(string skey, int val)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <param name="filed"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<bool> SetContainsAsync(string skey, int filed)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <param name="filed"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<bool> SetRemoveAsync(string skey, int filed)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<long> SetRandomMemberAsync(string skey)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<long> SetLengthAsync(string skey)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <param name="sval"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<long> ListRightPushAsync(string skey, string sval)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <param name="score"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<string> SortedSetRangeByScoreAsync(string skey, long score)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<long> SortedSetRangeByRankWithScoresAsync(string skey)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<long> ListLengthAsync(string skey)
+//        {
+//            throw new NotImplementedException();
+//        }
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<string> ListLeftPopAsync(string skey)
+//        {
+//            throw new NotImplementedException();
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <param name="skey"></param>
+//        /// <param name="start"></param>
+//        /// <param name="stop"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<List<string>> ListRangeAsync(string skey, int start = 0, int stop = 30)
+//        {
+//            throw new NotImplementedException();
+//        }
+
+//        /// <summary>
+//        /// 
+//        /// </summary>
+//        /// <typeparam name="T"></typeparam>
+//        /// <param name="skey"></param>
+//        /// <param name="start"></param>
+//        /// <param name="stop"></param>
+//        /// <returns></returns>
+//        /// <exception cref="NotImplementedException"></exception>
+//        public Task<List<T>> ListRangeAsync<T>(string skey, int start = 0, int stop = 30)
+//        {
+//            throw new NotImplementedException();
+//        }
+
+//        #endregion
+
+
+//    }
+
+//}
framework/PasteApeart.Handler/redis/MemoryClient.cs
diff --git a/framework/PasteApeart.Handler/redis/MemoryClient.cs b/framework/PasteApeart.Handler/redis/MemoryClient.cs
index 229d2a2..c6cd5d3 100644
--- a/framework/PasteApeart.Handler/redis/MemoryClient.cs
+++ b/framework/PasteApeart.Handler/redis/MemoryClient.cs
@@ -22,64 +22,82 @@ namespace PasteApeart.Handler.redis
             _memoryCache = memoryCache;
             key_hash_set = new ConcurrentDictionary<string, ConcurrentDictionary<string, string>>();
             key_hash_num = new ConcurrentDictionary<string, ConcurrentDictionary<string, long>>();
+            key_set = new ConcurrentDictionary<string, ConcurrentDictionary<int, byte>>();
+            key_list = new ConcurrentDictionary<string, List<string>>();
         }
 
-        ///// <summary>
-        ///// 
-        ///// </summary>
-        //private ConcurrentDictionary<string, string> key_val;
+        private ConcurrentDictionary<string, ConcurrentDictionary<string, string>> key_hash_set;
+        private ConcurrentDictionary<string, ConcurrentDictionary<string, long>> key_hash_num;
 
-        ///// <summary>
-        ///// 
-        ///// </summary>
-        //private ConcurrentDictionary<string, List<SortScore>> key_sort_set;
+        /// <summary>
+        /// Set(整数集合) 支持
+        /// </summary>
+        private ConcurrentDictionary<string, ConcurrentDictionary<int, byte>> key_set;
 
         /// <summary>
-        /// 
+        /// List 支持
         /// </summary>
-        private ConcurrentDictionary<string, ConcurrentDictionary<string, string>> key_hash_set;
+        private ConcurrentDictionary<string, List<string>> key_list;
 
         /// <summary>
+        /// List 操作锁
+        /// </summary>
+        private readonly object _listLock = new object();
+        /// <summary>
         /// 
         /// </summary>
-        private ConcurrentDictionary<string, ConcurrentDictionary<string, long>> key_hash_num;
-
         public bool IsRedis { get => false; }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public bool Delete(string key)
         {
             _memoryCache.Remove(key);
+            key_hash_set.TryRemove(key, out _);
+            key_hash_num.TryRemove(key, out _);
+            key_set.TryRemove(key, out _);
+            key_list.TryRemove(key, out _);
             return true;
         }
-
         /// <summary>
-        /// error
+        /// 
         /// </summary>
         /// <param name="key"></param>
         /// <returns></returns>
         public Task<bool> DeleteAsync(string key)
         {
-            return Task.Run<bool>(() =>
-            {
-                return Delete(key);
-            });
+            return Task.FromResult(Delete(key));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public bool Exists(string key)
         {
-            return _memoryCache.TryGetValue(key, out var val);
-            //throw new NotImplementedException();
+            if (_memoryCache.TryGetValue(key, out var _)) return true;
+            if (key_hash_set.ContainsKey(key)) return true;
+            if (key_hash_num.ContainsKey(key)) return true;
+            if (key_set.ContainsKey(key)) return true;
+            if (key_list.ContainsKey(key)) return true;
+            return false;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public T GetObject<T>(string key)
         {
             if (_memoryCache.TryGetValue(key, out string val))
             {
-                return JsonSerializer.Deserialize<T>(val, JsonConfig.Options);// JsonConvert.DeserializeObject<T>(val);
+                return JsonSerializer.Deserialize<T>(val, JsonConfig.Options);
             }
             return default(T);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -92,71 +110,100 @@ namespace PasteApeart.Handler.redis
                 return val;
             }
             return "";
-            // throw new NotImplementedException();
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public Task<T> GetObjectAsync<T>(string key)
         {
-            return Task.Run<T>(() =>
-            {
-                return GetObject<T>(key);
-            });
+            return Task.FromResult(GetObject<T>(key));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public Task<string> GetAsync(string key)
         {
-            return Task.Run<string>(() =>
-            {
-                return Get(key);
-            });
+            return Task.FromResult(Get(key));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public string GetStringValue(string key)
         {
             return Get(key);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="sunkey"></param>
+        /// <returns></returns>
         public string HashGet(string key, string sunkey)
         {
-            throw new NotImplementedException();
+            if (key_hash_set.TryGetValue(key, out var val) && val.TryGetValue(sunkey, out var _val))
+            {
+                return _val;
+            }
+            if (key_hash_num.TryGetValue(key, out var numVal) && numVal.TryGetValue(sunkey, out var _numVal))
+            {
+                return _numVal.ToString();
+            }
+            return string.Empty;
         }
 
-        public HashEntry[] HashGetAll(string key)
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public HashEntry[] HashGetAllEntry(string key)
         {
-            throw new NotImplementedException();
+            if (key_hash_set.TryGetValue(key, out var val))
+            {
+                return val.Select(x => new HashEntry(x.Key, x.Value)).ToArray();
+            }
+            if (key_hash_num.TryGetValue(key, out var numVal))
+            {
+                return numVal.Select(x => new HashEntry(x.Key, x.Value)).ToArray();
+            }
+            return Array.Empty<HashEntry>();
         }
 
-        //public Task<HashEntry[]> HashGetAllAsync(string key)
-        //{
-        //    throw new NotImplementedException();
-        //}
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public async Task<HashEntry[]> HashGetAllEntryAsync(string key)
+        {
+            var result = HashGetAllEntry(key);
+            return await Task.FromResult(result);
 
+        }
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="sunkey"></param>
+        /// <param name="isnum"></param>
         /// <returns></returns>
         public Task<string> HashGetAsync(string key, string sunkey, bool isnum = false)
         {
-            if (key_hash_set.TryGetValue(key, out var val))
-            {
-                if (val != null && val != default)
-                {
-                    if (val.TryGetValue(sunkey, out var _val))
-                    {
-                        return Task.FromResult(_val);
-                    }
-                }
-            }
-            return Task.FromResult(String.Empty);
+            return Task.FromResult(HashGet(key, sunkey));
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
+        /// <param name="isNum"></param>
         /// <returns></returns>
         public async Task<int> HashGetIntFieldAsync(string key, string field, bool isNum = false)
         {
@@ -168,12 +215,12 @@ namespace PasteApeart.Handler.redis
             }
             return default(int);
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
+        /// <param name="isNum"></param>
         /// <returns></returns>
         public async Task<long> HashGetLongFieldAsync(string key, string field, bool isNum = false)
         {
@@ -185,31 +232,53 @@ namespace PasteApeart.Handler.redis
             }
             return default(long);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="vals"></param>
         public void HashSet(string key, HashEntry[] vals)
         {
-            throw new NotImplementedException();
+            var dict = key_hash_set.GetOrAdd(key, _ => new ConcurrentDictionary<string, string>());
+            foreach (var entry in vals)
+            {
+                dict[entry.Name.ToString()] = entry.Value.ToString();
+            }
         }
-
-        //public void HashSetAsync(string key, HashEntry[] vals)
-        //{
-        //    throw new NotImplementedException();
-        //}
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="seconds"></param>
+        /// <returns></returns>
         public bool Lock(string key, int seconds)
         {
-            return false;
+            // 本地缓存模拟锁:若不存在则创建,存在则失败
+            var lockKey = "__lock__" + key;
+            if (_memoryCache.TryGetValue(lockKey, out _))
+            {
+                return false;
+            }
+            Set(lockKey, "1", seconds);
+            return true;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="seconds"></param>
+        /// <returns></returns>
         public Task<bool> LockAsync(string key, int seconds)
         {
-            //return Task.Run<bool>(() =>
-            //{
-            //    return Lock(key, seconds);
-            //});
-            return Task.FromResult(true);
+            return Task.FromResult(Lock(key, seconds));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="expiry"></param>
+        /// <returns></returns>
         public bool Set(string key, string value, TimeSpan? expiry = null)
         {
             using (var wcache = _memoryCache.CreateEntry(key))
@@ -217,30 +286,37 @@ namespace PasteApeart.Handler.redis
                 wcache.Value = value;
                 if (expiry == null)
                 {
-                    wcache.AbsoluteExpiration = System.DateTimeOffset.Now.AddSeconds(30);
+                    wcache.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(30);
                 }
                 else
                 {
                     wcache.AbsoluteExpiration = DateTimeOffset.Now.Add((TimeSpan)expiry);
                 }
             }
-
             return true;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="seconds"></param>
+        /// <returns></returns>
         public bool Set(string key, string value, int seconds)
         {
             using (var wcache = _memoryCache.CreateEntry(key))
             {
                 wcache.Value = value;
-
-                wcache.AbsoluteExpiration = System.DateTimeOffset.Now.AddSeconds(seconds);
-
+                wcache.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(seconds);
             }
-
             return true;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
         public bool Set(string key, string value)
         {
             using (var wcache = _memoryCache.CreateEntry(key))
@@ -249,52 +325,84 @@ namespace PasteApeart.Handler.redis
             }
             return true;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="expiry"></param>
+        /// <returns></returns>
         public bool SetObject<T>(string key, T value, TimeSpan? expiry = null)
         {
-
             return Set(key, JsonSerializer.Serialize<T>(value, JsonConfig.Options), expiry);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="seconds"></param>
+        /// <returns></returns>
         public bool SetObject<T>(string key, T value, int seconds)
         {
             return Set(key, JsonSerializer.Serialize<T>(value, JsonConfig.Options), seconds);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="expiry"></param>
+        /// <returns></returns>
         public Task<bool> SetAsync(string key, string value, TimeSpan? expiry = null)
         {
-            return Task.Run<bool>(() =>
-            {
-                return Set(key, value, expiry);
-            });
+            return Task.FromResult(Set(key, value, expiry));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="seconds"></param>
+        /// <returns></returns>
         public Task<bool> SetAsync(string key, string value, int seconds)
         {
-            return Task.Run<bool>(() =>
-            {
-                return Set(key, value, seconds);
-            });
+            return Task.FromResult(Set(key, value, seconds));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="second"></param>
+        /// <returns></returns>
         public Task<bool> SetObjectAsync<T>(string key, T value, int second)
         {
-            return Task.Run<bool>(() =>
-            {
-                return SetObject(key, value, second);
-            });
+            return Task.FromResult(SetObject(key, value, second));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="expiry"></param>
+        /// <returns></returns>
         public bool SetExpire(string key, TimeSpan? expiry)
         {
             if (_memoryCache.TryGetValue(key, out string sval))
             {
-
                 return Set(key, sval, expiry);
             }
             return false;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="seconds"></param>
+        /// <returns></returns>
         public bool SetExpire(string key, int seconds)
         {
             if (_memoryCache.TryGetValue(key, out string sval))
@@ -303,38 +411,57 @@ namespace PasteApeart.Handler.redis
             }
             return false;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="seconds"></param>
+        /// <returns></returns>
         public Task<bool> SetExpireAsync(string key, int seconds)
         {
-            return Task.Run<bool>(() =>
-            {
-                return SetExpire(key, seconds);
-            });
+            return Task.FromResult(SetExpire(key, seconds));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="expiry"></param>
+        /// <returns></returns>
         public Task<bool> SetExpireAsync(string key, TimeSpan? expiry)
         {
-            return Task.Run<bool>(() =>
-            {
-                return SetExpire(key, expiry);
-            });
+            return Task.FromResult(SetExpire(key, expiry));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="val"></param>
+        /// <param name="second"></param>
+        /// <returns></returns>
         public bool SetValue(string key, string val, int second)
         {
             return Set(key, val, second);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="val"></param>
+        /// <returns></returns>
         public bool SetValue(string key, string val)
         {
             return Set(key, val);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public bool UnLock(string key)
         {
-            return false;
+            _memoryCache.Remove("__lock__" + key);
+            return true;
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -342,121 +469,21 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         public Task<bool> UnLockAsync(string key)
         {
-            //return Task.Run<bool>(() =>
-            //{
-            //    return UnLock(key);
-            //});
-            return Task.FromResult(true);
+            return Task.FromResult(UnLock(key));
         }
-
-        ///// <summary>
-        ///// 
-        ///// </summary>
-        ///// <param name="key"></param>
-        ///// <param name="vals"></param>
-        ///// <returns></returns>
-        //public async Task HashSetAsync(string key, HashEntry[] vals, bool isnum = false)
-        //{
-        //    await Task.Run(() =>
-        //    {
-        //        if (isnum)
-        //        {
-        //            if(key_hash_num.TryGetValue(key, out var _hash))
-        //            {
-        //                foreach (var entry in vals)
-        //                {
-        //                    _hash.AddOrUpdate(entry.Name.ToString(), long.Parse(entry.Value.ToString()), (k, oldValue) => long.Parse(entry.Value.ToString()));
-        //                }
-        //            }
-        //            else
-        //            {
-        //                _hash = new ConcurrentDictionary<string, long>();
-
-        //                foreach (var entry in vals)
-        //                {
-        //                    _hash.AddOrUpdate(entry.Name.ToString(), long.Parse(entry.Value.ToString()), (k, oldValue) => long.Parse(entry.Value.ToString()));
-        //                }
-        //                key_hash_num.TryAdd(key, _hash);
-        //            }
-        //        }
-        //        else
-        //        {
-        //            key_hash_set.TryGetValue(key, out var _hash);
-        //            if (_hash == null || _hash == default)
-        //            {
-        //                _hash = new ConcurrentDictionary<string, string>();
-        //            }
-        //            foreach (var entry in vals)
-        //            {
-        //                _hash.AddOrUpdate(entry.Name.ToString(), entry.Value.ToString(), (k, oldValue) => entry.Value.ToString());
-        //            }
-        //            key_hash_set.AddOrUpdate(key, _hash, (k, oldvalue) => _hash);
-        //        }
-
-
-        //    });
-        //}
-
-        //public List<HashKeyValue> HashGetAll(string key)
-        //{
-        //    throw new NotImplementedException();
-        //}
-
-        //public Task<List<HashKeyValue>> HashGetAllAsync(string key)
-        //{
-        //    throw new NotImplementedException();
-        //}
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="vals"></param>
         public void HashSet(string key, List<HashKeyValue> vals)
         {
-            throw new NotImplementedException();
+            var dict = key_hash_set.GetOrAdd(key, _ => new ConcurrentDictionary<string, string>());
+            foreach (var entry in vals)
+            {
+                dict[entry.Key] = entry.Value;
+            }
         }
-
-        ///// <summary>
-        ///// 
-        ///// </summary>
-        ///// <param name="key"></param>
-        ///// <param name="vals"></param>
-        ///// <returns></returns>
-        //public async Task HashSetAsync(string key, List<HashKeyValue> vals, bool isnum = false)
-        //{
-        //    await Task.Run(() =>
-        //    {
-        //        if (isnum)
-        //        {
-        //            if(key_hash_num.TryGetValue(key, out var _hash))
-        //            {
-        //                foreach (var entry in vals)
-        //                {
-        //                    _hash.AddOrUpdate(entry.Key, long.Parse(entry.Value), (k, oldValue) => long.Parse(entry.Value));
-        //                }
-        //            }
-        //            else
-        //            {
-        //                _hash = new ConcurrentDictionary<string, long>();
-        //                foreach (var entry in vals)
-        //                {
-        //                    _hash.AddOrUpdate(entry.Key, long.Parse(entry.Value), (k, oldValue) => long.Parse(entry.Value));
-        //                }
-        //                key_hash_num.TryAdd(key, _hash);
-        //            }
-        //        }
-        //        else
-        //        {
-        //            key_hash_set.TryGetValue(key, out var _hash);
-        //            if (_hash == null || _hash == default)
-        //            {
-        //                _hash = new ConcurrentDictionary<string, string>();
-        //            }
-        //            foreach (var entry in vals)
-        //            {
-        //                _hash.AddOrUpdate(entry.Key, entry.Value, (k, oldValue) => entry.Value);
-        //            }
-        //            key_hash_set.AddOrUpdate(key, _hash, (k, oldvalue) => _hash);
-        //        }
-        //    });
-        //}
-
         /// <summary>
         /// 
         /// </summary>
@@ -466,51 +493,10 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         public Task<long> HashIncrementAsync(string key, string field, long num = 1)
         {
-            var _result = num;
-            key_hash_num.TryGetValue(key, out var _hash);
-            if (_hash == null || _hash == default)
-            {
-                _hash = new ConcurrentDictionary<string, long>() { };
-                _hash.TryAdd(field, num);
-                key_hash_num.TryAdd(key, _hash);
-            }
-            else
-            {
-                if (_hash.ContainsKey(field))
-                {
-                    _hash[field] = _hash[field] + num;
-                    _result = _hash[field];
-                }
-                else
-                {
-                    _hash.TryAdd(field, num);
-                }
-            }
-            return Task.FromResult(_result);
+            var dict = key_hash_num.GetOrAdd(key, _ => new ConcurrentDictionary<string, long>());
+            var result = dict.AddOrUpdate(field, num, (k, old) => old + num);
+            return Task.FromResult(result);
         }
-
-        ///// <summary>
-        ///// 
-        ///// </summary>
-        ///// <param name="key"></param>
-        ///// <param name="start"></param>
-        ///// <param name="stop"></param>
-        ///// <returns></returns>
-        //public Task<SortedSetEntry[]> SortedSetRangeByRankWithScoresAsync(string key, int start = 0, int stop = 1)
-        //{
-        //    if (key_hash_num.TryGetValue(key, out var _hash))
-        //    {
-        //        var list = new List<SortedSetEntry>();
-        //        var hits = _hash.Where(x => x.Value >= start && x.Value < stop).ToList();
-        //        foreach (var item in hits)
-        //        {
-        //            list.Add(new SortedSetEntry(item.Key, item.Value));
-        //        }
-        //        return Task.FromResult(list.ToArray());
-        //    }
-        //    return Task.FromResult(new SortedSetEntry[] { });
-        //}
-
         /// <summary>
         /// 
         /// </summary>
@@ -518,7 +504,6 @@ namespace PasteApeart.Handler.redis
         /// <param name="start"></param>
         /// <param name="stop"></param>
         /// <returns></returns>
-        /// <exception cref="NotImplementedException"></exception>
         public Task<RedisValue[]> SortedSetRangeByScoreAsync(string key, long start = 0, long stop = 1)
         {
             if (key_hash_num.TryGetValue(key, out var _hash))
@@ -536,7 +521,6 @@ namespace PasteApeart.Handler.redis
             }
             return Task.FromResult(new RedisValue[] { });
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -546,29 +530,10 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         public Task<long> SortedSetIncrementAsync(string key, string field, long num = 1)
         {
-            var _result = num;
-            key_hash_num.TryGetValue(key, out var _hash);
-            if (_hash == null || _hash == default)
-            {
-                _hash = new ConcurrentDictionary<string, long>() { };
-                _hash.TryAdd(field, num);
-                key_hash_num.TryAdd(key, _hash);
-            }
-            else
-            {
-                if (_hash.ContainsKey(field))
-                {
-                    _hash[field] = _hash[field] + num;
-                    _result = _hash[field];
-                }
-                else
-                {
-                    _hash.TryAdd(field, num);
-                }
-            }
-            return Task.FromResult(_result);
+            var dict = key_hash_num.GetOrAdd(key, _ => new ConcurrentDictionary<string, long>());
+            var result = dict.AddOrUpdate(field, num, (k, old) => old + num);
+            return Task.FromResult(result);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -578,29 +543,10 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         public Task<long> SortedSetDecrementAsync(string key, string field, long num)
         {
-            var _result = num;
-            key_hash_num.TryGetValue(key, out var _hash);
-            if (_hash == null || _hash == default)
-            {
-                _hash = new ConcurrentDictionary<string, long>() { };
-                _hash.TryAdd(field, num);
-                key_hash_num.TryAdd(key, _hash);
-            }
-            else
-            {
-                if (_hash.ContainsKey(field))
-                {
-                    _hash[field] = _hash[field] - num;
-                    _result = _hash[field];
-                }
-                else
-                {
-                    _hash.TryAdd(field, num);
-                }
-            }
-            return Task.FromResult(_result);
+            var dict = key_hash_num.GetOrAdd(key, _ => new ConcurrentDictionary<string, long>());
+            var result = dict.AddOrUpdate(field, -num, (k, old) => old - num);
+            return Task.FromResult(result);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -609,18 +555,12 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         public Task<bool> SortedSetRemoveAsync(string key, string field)
         {
-            var _result = false;
             if (key_hash_num.TryGetValue(key, out var _hash))
             {
-                if (_hash.ContainsKey(field))
-                {
-                    _hash.Remove(field, out _);
-                    _result = true;
-                }
+                return Task.FromResult(_hash.TryRemove(field, out _));
             }
-            return Task.FromResult(_result);
+            return Task.FromResult(false);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -630,44 +570,24 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         public Task<bool> SortedSetAddAsync(string key, string field, long num)
         {
-            if (key_hash_num.TryGetValue(key, out var _hash))
-            {
-                if (_hash.ContainsKey(field))
-                {
-                    _hash[field] = num;
-                }
-                else
-                {
-                    _hash.TryAdd(field, num);
-                }
-            }
-            else
-            {
-                _hash = new ConcurrentDictionary<string, long>() { };
-                _hash.TryAdd(field, num);
-                key_hash_num.TryAdd(key, _hash);
-            }
+            var dict = key_hash_num.GetOrAdd(key, _ => new ConcurrentDictionary<string, long>());
+            dict[field] = num;
             return Task.FromResult(true);
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <returns></returns>
-        /// <exception cref="NotImplementedException"></exception>
         public Task<bool> ExistsAsync(string key)
         {
-            var _result = _memoryCache.TryGetValue(key, out var val);
-            return Task.FromResult(_result);
+            return Task.FromResult(Exists(key));
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <returns></returns>
-        /// <exception cref="NotImplementedException"></exception>
         public Task<List<HashKeyValue>> HashGetAllAsync(string key)
         {
             if (key_hash_set.TryGetValue(key, out var _hash))
@@ -684,13 +604,12 @@ namespace PasteApeart.Handler.redis
                 var finds = new List<HashKeyValue>();
                 foreach (var item in _hash_num)
                 {
-                    finds.Add(new HashKeyValue { Key = item.Key, Value = item.ToString() });
+                    finds.Add(new HashKeyValue { Key = item.Key, Value = item.Value.ToString() });
                 }
                 return Task.FromResult(finds);
             }
             return Task.FromResult(new List<HashKeyValue> { });
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -699,30 +618,10 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         public Task<long> HashDecrementAsync(string key, string field)
         {
-            var num = 1;
-            long _result = num;
-            key_hash_num.TryGetValue(key, out var _hash);
-            if (_hash == null || _hash == default)
-            {
-                _hash = new ConcurrentDictionary<string, long>() { };
-                _hash.TryAdd(field, 0 - num);
-                key_hash_num.TryAdd(key, _hash);
-            }
-            else
-            {
-                if (_hash.ContainsKey(field))
-                {
-                    _hash[field] = _hash[field] - num;
-                    _result = _hash[field];
-                }
-                else
-                {
-                    _hash.TryAdd(field, num);
-                }
-            }
-            return Task.FromResult(_result);
+            var dict = key_hash_num.GetOrAdd(key, _ => new ConcurrentDictionary<string, long>());
+            var result = dict.AddOrUpdate(field, -1, (k, old) => old - 1);
+            return Task.FromResult(result);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -732,33 +631,23 @@ namespace PasteApeart.Handler.redis
         public Task<bool> HashExistsAsync(string key, string filed)
         {
             var _result = false;
-
-            if (key_hash_num.TryGetValue(key, out var _hash))
+            if (key_hash_num.TryGetValue(key, out var _hash) && _hash.ContainsKey(filed))
             {
-                if (_hash.ContainsKey(filed))
-                {
-                    _result = true;
-                }
+                _result = true;
             }
-            if (!_result)
+            if (!_result && key_hash_set.TryGetValue(key, out var hash_key) && hash_key.ContainsKey(filed))
             {
-                if (key_hash_set.TryGetValue(key, out var hash_key))
-                {
-                    if (hash_key.ContainsKey(filed))
-                    {
-                        _result = true;
-                    }
-                }
+                _result = true;
             }
-            return Task.FromResult(true);
+            return Task.FromResult(_result);
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
         /// <param name="value"></param>
+        /// <param name="isnum"></param>
         /// <returns></returns>
         public async Task HashSetAsync(string key, string field, RedisValue value, bool isnum = false)
         {
@@ -766,33 +655,19 @@ namespace PasteApeart.Handler.redis
             {
                 if (isnum)
                 {
-                    if (key_hash_num.TryGetValue(key, out var hash_key))
-                    {
-                        hash_key.AddOrUpdate(field, long.Parse(value.ToString()), (n, o) => long.Parse(value.ToString()));
-                    }
-                    else
+                    var dict = key_hash_num.GetOrAdd(key, _ => new ConcurrentDictionary<string, long>());
+                    if (long.TryParse(value.ToString(), out var numVal))
                     {
-                        var find = new ConcurrentDictionary<string, long>();
-                        find.TryAdd(field, long.Parse(value.ToString()));
-                        key_hash_num.TryAdd(key, find);
+                        dict[field] = numVal;
                     }
                 }
                 else
                 {
-                    if (key_hash_set.TryGetValue(key, out var hash_key))
-                    {
-                        hash_key.AddOrUpdate(field, value.ToString(), (n, o) => value.ToString());
-                    }
-                    else
-                    {
-                        var find = new ConcurrentDictionary<string, string>();
-                        find.TryAdd(field, value.ToString());
-                        key_hash_set.TryAdd(key, find);
-                    }
+                    var dict = key_hash_set.GetOrAdd(key, _ => new ConcurrentDictionary<string, string>());
+                    dict[field] = value.ToString();
                 }
             });
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -802,20 +677,16 @@ namespace PasteApeart.Handler.redis
         /// <returns></returns>
         public Task<T> HashGetObjectAsync<T>(string key, string field)
         {
-            if (key_hash_set.TryGetValue(key, out var hash_key))
+            if (key_hash_set.TryGetValue(key, out var hash_key) && hash_key.TryGetValue(field, out var _value))
             {
-                if (hash_key.TryGetValue(field, out var _value))
+                if (!String.IsNullOrEmpty(_value))
                 {
-                    if (!String.IsNullOrEmpty(_value))
-                    {
-                        var t = JsonSerializer.Deserialize<T>(_value, JsonConfig.Options);// Newtonsoft.Json.JsonConvert.DeserializeObject<T>(_value);
-                        return Task.FromResult(t);
-                    }
+                    var t = JsonSerializer.Deserialize<T>(_value, JsonConfig.Options);
+                    return Task.FromResult(t);
                 }
             }
             return Task.FromResult(default(T));
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -827,22 +698,10 @@ namespace PasteApeart.Handler.redis
         public Task<bool> HashSetObjectAsync<T>(string key, string field, T entity)
         {
             var value = JsonSerializer.Serialize<T>(entity, JsonConfig.Options);
-            //Newtonsoft.Json.JsonConvert.SerializeObject(entity);
-            if (key_hash_set.TryGetValue(key, out var hash_key))
-            {
-
-                hash_key.AddOrUpdate(field, value, (n, o) => value);
-
-            }
-            else
-            {
-                var find = new ConcurrentDictionary<string, string>();
-                find.TryAdd(field, value);
-                key_hash_set.TryAdd(key, find);
-            }
+            var dict = key_hash_set.GetOrAdd(key, _ => new ConcurrentDictionary<string, string>());
+            dict[field] = value;
             return Task.FromResult(true);
         }
-
         /// <summary>
         /// 
         /// </summary>
@@ -850,34 +709,30 @@ namespace PasteApeart.Handler.redis
         /// <param name="pattern"></param>
         /// <param name="page"></param>
         /// <param name="size"></param>
+        /// <param name="isincom"></param>
         /// <returns></returns>
         public Task<List<HashEntry>> HashScanAsync(string key, string pattern, int page, int size, bool isincom = false)
         {
+            //Func<KeyValuePair<string, long>, bool> numFilter = null;
+            //Func<KeyValuePair<string, string>, bool> setFilter = null;
+
+            var position = 3; //1left 2right 3like
+            if (pattern.StartsWith("*")) position = 1;
+            if (pattern.EndsWith("*"))
+            {
+                if (position == 1) position = 3;
+                else position = 2;
+            }
+            var realPattern = pattern.Replace("*", "");
+
             if (isincom)
             {
                 if (key_hash_num.TryGetValue(key, out var hash_key))
                 {
-                    var position = 3;//1left 2right 3like
-                    if (pattern.StartsWith("*"))
-                    {
-                        position = 1;
-                    }
-                    if (pattern.EndsWith("*"))
-                    {
-                        if (position == 1)
-                        {
-                            position = 3;
-                        }
-                        else
-                        {
-                            position = 2;
-                        }
-                    }
-                    pattern = pattern.Replace("*", "");
                     var vals = hash_key
-                        .PasteWhereIf(position == 1, x => x.Key.EndsWith(pattern))
-                        .PasteWhereIf(position == 2, x => x.Key.StartsWith(pattern))
-                        .PasteWhereIf(position == 3, x => x.Key.Contains(pattern))
+                        .PasteWhereIf(position == 1, x => x.Key.EndsWith(realPattern))
+                        .PasteWhereIf(position == 2, x => x.Key.StartsWith(realPattern))
+                        .PasteWhereIf(position == 3, x => x.Key.Contains(realPattern))
                         .OrderBy(x => x.Key)
                         .ToList();
                     var start = (page - 1) * size;
@@ -890,10 +745,7 @@ namespace PasteApeart.Handler.redis
                             var item = vals[k];
                             list.Add(new HashEntry(item.Key, item.Value));
                         }
-                        if (k > end)
-                        {
-                            break;
-                        }
+                        if (k >= end) break;
                     }
                     return Task.FromResult(list);
                 }
@@ -902,27 +754,10 @@ namespace PasteApeart.Handler.redis
             {
                 if (key_hash_set.TryGetValue(key, out var hash_key))
                 {
-                    var position = 3;//1left 2right 3like
-                    if (pattern.StartsWith("*"))
-                    {
-                        position = 1;
-                    }
-                    if (pattern.EndsWith("*"))
-                    {
-                        if (position == 1)
-                        {
-                            position = 3;
-                        }
-                        else
-                        {
-                            position = 2;
-                        }
-                    }
-                    pattern = pattern.Replace("*", "");
                     var vals = hash_key
-                        .PasteWhereIf(position == 1, x => x.Key.StartsWith(pattern))
-                        .PasteWhereIf(position == 2, x => x.Key.EndsWith(pattern))
-                        .PasteWhereIf(position == 3, x => x.Key.Contains(pattern))
+                        .PasteWhereIf(position == 1, x => x.Key.StartsWith(realPattern))
+                        .PasteWhereIf(position == 2, x => x.Key.EndsWith(realPattern))
+                        .PasteWhereIf(position == 3, x => x.Key.Contains(realPattern))
                         .OrderBy(x => x.Key)
                         .ToList();
                     var start = (page - 1) * size;
@@ -935,22 +770,19 @@ namespace PasteApeart.Handler.redis
                             var item = vals[k];
                             list.Add(new HashEntry(item.Key, item.Value));
                         }
-                        if (k > end)
-                        {
-                            break;
-                        }
+                        if (k >= end) break;
                     }
                     return Task.FromResult(list);
                 }
             }
             return Task.FromResult(new List<HashEntry> { });
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="fields"></param>
+        /// <param name="isnum"></param>
         /// <returns></returns>
         public Task<RedisValue[]> HashGetAsync(string key, RedisValue[] fields, bool isnum = false)
         {
@@ -961,10 +793,7 @@ namespace PasteApeart.Handler.redis
                 {
                     var haves = hash_key.Where(x => fis.Contains(x.Key)).ToList();
                     var reds = new List<RedisValue>();
-                    foreach (var kv in haves)
-                    {
-                        reds.Add(kv.Value);
-                    }
+                    foreach (var kv in haves) reds.Add(kv.Value);
                     return Task.FromResult(reds.ToArray());
                 }
             }
@@ -974,168 +803,115 @@ namespace PasteApeart.Handler.redis
                 {
                     var haves = hash_key.Where(x => fis.Contains(x.Key)).ToList();
                     var reds = new List<RedisValue>();
-                    foreach (var kv in haves)
-                    {
-                        reds.Add(kv.Value);
-                    }
+                    foreach (var kv in haves) reds.Add(kv.Value);
                     return Task.FromResult(reds.ToArray());
                 }
             }
             return Task.FromResult(new RedisValue[] { });
         }
-
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
         /// <returns></returns>
-        public async Task<bool> HashDeleteAsync(string key, string field)
+        public Task<bool> HashDeleteAsync(string key, string field)
         {
-            await Task.Run(() =>
+            var _result = false;
+            if (key_hash_set.TryGetValue(key, out var hash_key) && hash_key.TryRemove(field, out _))
             {
-                var _result = false;
-                if (key_hash_set.TryGetValue(key, out var hash_key))
-                {
-                    if (hash_key.ContainsKey(field))
-                    {
-                        _result = true;
-                    }
-                    hash_key.Remove(field, out var abc);
-                }
-                if (!_result)
-                {
-                    if (key_hash_num.TryGetValue(key, out var _hash))
-                    {
-                        if (_hash.ContainsKey(field))
-                        {
-                            _result = true;
-                        }
-                        _hash.Remove(field, out var abc);
-                    }
-                }
-                return _result;
-            });
-            return false;
+                _result = true;
+            }
+            if (key_hash_num.TryGetValue(key, out var _hash) && _hash.TryRemove(field, out _))
+            {
+                _result = true;
+            }
+            return Task.FromResult(_result);
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="fields"></param>
         /// <returns></returns>
-        /// <exception cref="NotImplementedException"></exception>
         public Task<bool> HashDeleteAsync(string key, RedisValue[] fields)
         {
             var fis = fields.Select(x => x.ToString()).ToArray();
+            var _result = false;
             if (key_hash_set.TryGetValue(key, out var hash_key))
             {
                 foreach (var kv in fis)
                 {
-                    hash_key.Remove(kv, out var va);
+                    if (hash_key.TryRemove(kv, out _)) _result = true;
                 }
-                var haves = hash_key.Where(x => fis.Contains(x.Key)).ToList();
-                var reds = new List<RedisValue>();
-                foreach (var kv in haves)
+            }
+            if (key_hash_num.TryGetValue(key, out var num_key))
+            {
+                foreach (var kv in fis)
                 {
-                    reds.Add(kv.Value);
+                    if (num_key.TryRemove(kv, out _)) _result = true;
                 }
-                return Task.FromResult(true);
             }
-            return Task.FromResult(false);
+            return Task.FromResult(_result);
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <returns></returns>
-        /// <exception cref="NotImplementedException"></exception>
         public Task<long> HashLengthAsync(string key)
         {
-            if (key_hash_set.TryGetValue(key, out var hash_key))
-            {
-                return Task.FromResult((long)hash_key.Keys.Count);
-            }
-            return Task.FromResult((long)0);
+            long count = 0;
+            if (key_hash_set.TryGetValue(key, out var hash_key)) count += hash_key.Count;
+            if (key_hash_num.TryGetValue(key, out var num_key)) count += num_key.Count;
+            return Task.FromResult(count);
         }
-
         /// <summary>
-        /// 打印
+        /// 
         /// </summary>
         /// <returns></returns>
         public string Print()
         {
             var sb = new StringBuilder();
-
             if (key_hash_set != null && key_hash_set.Any())
             {
-                //sb.AppendLine(Newtonsoft.Json.JsonConvert.SerializeObject(key_hash_set));
                 sb.AppendLine(JsonSerializer.Serialize(key_hash_set, JsonConfig.Options));
             }
-
             if (key_hash_num != null && key_hash_num.Any())
             {
-                //sb.AppendLine(Newtonsoft.Json.JsonConvert.SerializeObject(key_hash_num));
-                sb.AppendLine(JsonSerializer.Serialize(key_hash_set, JsonConfig.Options));
+                sb.AppendLine(JsonSerializer.Serialize(key_hash_num, JsonConfig.Options));
+            }
+            if (key_set != null && key_set.Any())
+            {
+                sb.AppendLine(JsonSerializer.Serialize(key_set, JsonConfig.Options));
+            }
+            if (key_list != null && key_list.Any())
+            {
+                sb.AppendLine(JsonSerializer.Serialize(key_list, JsonConfig.Options));
             }
-
             return sb.ToString();
         }
 
-
         //------------------------------------------------
 
-
-        //private readonly IMemoryCache _memoryCache;
         private static readonly Random _random = new();
-
-        //public MemoryClient(IMemoryCache memoryCache)
-        //{
-        //    _memoryCache = memoryCache;
-        //}
-
-        //public bool IsRedis => false;
-
-        #region 同步方法
-
-        //public bool Delete(string key)
-        //{
-        //    _memoryCache.Remove(key);
-        //    return true;
-        //}
-
-        //public bool Exists(string key)
-        //{
-        //    return _memoryCache.TryGetValue(key, out _);
-        //}
-
-        //public string Get(string key)
-        //{
-        //    return _memoryCache.TryGetValue(key, out string? val) ? val ?? string.Empty : string.Empty;
-        //}
-
-        //public T GetObject<T>(string key)
-        //{
-        //    if (_memoryCache.TryGetValue(key, out string? val) && !string.IsNullOrEmpty(val))
-        //    {
-        //        return JsonConvert.DeserializeObject<T>(val);
-        //    }
-        //    return default;
-        //}
-
-        //public string GetStringValue(string key)
-        //{
-        //    return Get(key);
-        //}
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public object TryGetValue(string key)
         {
             return _memoryCache.TryGetValue(key, out var val) ? val : null;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="key"></param>
+        /// <param name="factory"></param>
+        /// <param name="expiration"></param>
+        /// <returns></returns>
         public T GetOrCreate<T>(string key, Func<ICacheEntry, T> factory, TimeSpan? expiration = null)
         {
             return _memoryCache.GetOrCreate(key, entry =>
@@ -1144,37 +920,13 @@ namespace PasteApeart.Handler.redis
                 return factory(entry);
             });
         }
-
-        //public bool Set(string key, string value, TimeSpan? expiry = null)
-        //{
-        //    using var entry = _memoryCache.CreateEntry(key);
-        //    entry.Value = value;
-        //    SetCacheEntryOptions(entry, expiry);
-        //    return true;
-        //}
-
-        //public bool Set(string key, string value, int seconds)
-        //{
-        //    return Set(key, value, TimeSpan.FromSeconds(seconds));
-        //}
-
-        //public bool Set(string key, string value)
-        //{
-        //    using var entry = _memoryCache.CreateEntry(key);
-        //    entry.Value = value;
-        //    return true;
-        //}
-
-        //public bool SetObject<T>(string key, T value, TimeSpan? expiry = null)
-        //{
-        //    return Set(key, JsonConvert.SerializeObject(value), expiry);
-        //}
-
-        //public bool SetObject<T>(string key, T value, int seconds)
-        //{
-        //    return Set(key, JsonConvert.SerializeObject(value), TimeSpan.FromSeconds(seconds));
-        //}
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="value"></param>
+        /// <param name="expiry"></param>
+        /// <returns></returns>
         public bool CreateEntry(string key, object value, TimeSpan? expiry = null)
         {
             using var entry = _memoryCache.CreateEntry(key);
@@ -1183,51 +935,12 @@ namespace PasteApeart.Handler.redis
             return true;
         }
 
-        //public bool SetValue(string key, string val, int second)
-        //{
-        //    return Set(key, val, second);
-        //}
-
-        //public bool SetValue(string key, string val)
-        //{
-        //    return Set(key, val);
-        //}
-
-        //public bool SetExpire(string key, TimeSpan? expiry)
-        //{
-        //    if (_memoryCache.TryGetValue(key, out string? val))
-        //    {
-        //        return Set(key, val ?? string.Empty, expiry);
-        //    }
-        //    return false;
-        //}
-
-        //public bool SetExpire(string key, int seconds)
-        //{
-        //    return SetExpire(key, TimeSpan.FromSeconds(seconds));
-        //}
-
-        //public bool Lock(string key, int seconds)
-        //{
-        //    // MemoryCache 不支持分布式锁,直接返回 true
-        //    return true;
-        //}
-
-        //public bool UnLock(string key)
-        //{
-        //    return true;
-        //}
-
-        #endregion
-
-        #region 异步方法(同步包装,返回 Task)
-
-        //public Task<bool> DeleteAsync(string key)
-        //{
-        //    Delete(key);
-        //    return Task.FromResult(true);
-        //}
-
+        #region 异步方法
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="keys"></param>
+        /// <returns></returns>
         public Task BatchRemoveAsync(string[] keys)
         {
             if (keys != null)
@@ -1236,28 +949,20 @@ namespace PasteApeart.Handler.redis
                 {
                     if (!string.IsNullOrEmpty(key))
                     {
-                        _memoryCache.Remove(key);
+                        Delete(key);
                     }
                 }
             }
             return Task.CompletedTask;
         }
-
-        //public Task<bool> ExistsAsync(string key)
-        //{
-        //    return Task.FromResult(Exists(key));
-        //}
-
-        //public Task<string> GetAsync(string key)
-        //{
-        //    return Task.FromResult(Get(key));
-        //}
-
-        //public Task<T?> GetObjectAsync<T>(string key)
-        //{
-        //    return Task.FromResult(GetObject<T>(key));
-        //}
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="key"></param>
+        /// <param name="factory"></param>
+        /// <param name="expiration"></param>
+        /// <returns></returns>
         public Task<T> GetOrCreateAsync<T>(string key, Func<ICacheEntry, Task<T>> factory, TimeSpan? expiration = null)
         {
             return _memoryCache.GetOrCreateAsync(key, async entry =>
@@ -1267,114 +972,38 @@ namespace PasteApeart.Handler.redis
             });
         }
 
-        //public Task<bool> SetAsync(string key, string value, TimeSpan? expiry = null)
-        //{
-        //    return Task.FromResult(Set(key, value, expiry));
-        //}
-
-        //public Task<bool> SetAsync(string key, string value, int seconds)
-        //{
-        //    return Task.FromResult(Set(key, value, seconds));
-        //}
-
-        //public Task<bool> SetObjectAsync<T>(string key, T value, int second)
-        //{
-        //    return Task.FromResult(SetObject(key, value, second));
-        //}
-
-        //public Task<bool> SetExpireAsync(string key, int seconds)
-        //{
-        //    return Task.FromResult(SetExpire(key, seconds));
-        //}
-
-        //public Task<bool> SetExpireAsync(string key, TimeSpan? expiry)
-        //{
-        //    return Task.FromResult(SetExpire(key, expiry));
-        //}
-
-        //public Task<bool> LockAsync(string key, int seconds)
-        //{
-        //    return Task.FromResult(Lock(key, seconds));
-        //}
-
-        //public Task<bool> UnLockAsync(string key)
-        //{
-        //    return Task.FromResult(UnLock(key));
-        //}
-
         #endregion
 
         #region Hash 操作
-
-        //public string HashGet(string key, string subKey)
-        //{
-        //    if (_memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> dict)
-        //    {
-        //        return dict.TryGetValue(subKey, out var val) ? val : string.Empty;
-        //    }
-        //    return string.Empty;
-        //}
-
-        //public HashEntry[] HashGetAll(string key)
-        //{
-        //    if (_memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> dict)
-        //    {
-        //        return dict.Select(x => new HashEntry(x.Key, x.Value)).ToArray();
-        //    }
-        //    return Array.Empty<HashEntry>();
-        //}
-
-        //public void HashSet(string key, HashEntry[] vals)
-        //{
-        //    var dict = _memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> existing
-        //        ? existing
-        //        : new Dictionary<string, string>();
-
-        //    foreach (var entry in vals)
-        //    {
-        //        dict[entry.Name.ToString()] = entry.Value.ToString();
-        //    }
-
-        //    _memoryCache.Set(key, dict);
-        //}
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="subKey"></param>
+        /// <returns></returns>
         public Task<string> HashGetAsync(string key, string subKey)
         {
             return Task.FromResult(HashGet(key, subKey));
         }
-
-        //public Task<HashEntry[]> HashGetAllAsync(string key)
-        //{
-        //    return Task.FromResult(HashGetAll(key));
-        //}
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="vals"></param>
+        /// <returns></returns>
         public Task HashSetAsync(string key, HashEntry[] vals)
         {
             HashSet(key, vals);
             return Task.CompletedTask;
         }
-
-        ///// <summary>
-        ///// 
-        ///// </summary>
-        ///// <param name="key"></param>
-        ///// <param name="field"></param>
-        ///// <returns></returns>
-        //public Task<bool> HashDeleteAsync(string key, string field)
-        //{
-        //    if (_memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> dict)
-        //    {
-        //        if (dict.ContainsKey(field))
-        //        {
-        //            dict.Remove(field);
-        //        }
-        //    }
-        //    return Task.FromResult(true);
-        //}
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public Task<HashEntry> HashRandomFieldsWithValuesAsync(string key)
         {
-            if (_memoryCache.TryGetValue(key, out var obj) && obj is Dictionary<string, string> dict && dict.Count > 0)
+            if (key_hash_set.TryGetValue(key, out var dict) && dict.Count > 0)
             {
                 var keys = dict.Keys.ToArray();
                 var randomKey = keys[_random.Next(keys.Length)];
@@ -1382,21 +1011,26 @@ namespace PasteApeart.Handler.redis
             }
             return Task.FromResult(new HashEntry(string.Empty, string.Empty));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="field"></param>
+        /// <param name="num"></param>
+        /// <returns></returns>
         public Task<long> HashIncrementAsync(string key, RedisValue field, long num = 1)
         {
-            // MemoryCache 不支持原子增减,简单实现
-            var current = HashGet(key, field.ToString());
-            if (long.TryParse(current, out var value))
-            {
-                var newValue = value + num;
-                HashSet(key, new[] { new HashEntry(field, newValue.ToString()) });
-                return Task.FromResult(newValue);
-            }
-            HashSet(key, new[] { new HashEntry(field, num.ToString()) });
-            return Task.FromResult(num);
+            var dict = key_hash_num.GetOrAdd(key, _ => new ConcurrentDictionary<string, long>());
+            var result = dict.AddOrUpdate(field.ToString(), num, (k, old) => old + num);
+            return Task.FromResult(result);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="field"></param>
+        /// <param name="num"></param>
+        /// <returns></returns>
         public Task<long> HashDecrementAsync(string key, RedisValue field, long num = 1)
         {
             return HashIncrementAsync(key, field, -num);
@@ -1404,31 +1038,62 @@ namespace PasteApeart.Handler.redis
 
         #endregion
 
-        #region 未实现的方法(抛出明确异常)
-
-        //public void HashSet(string key, List<HashKeyValue> vals)
-        //{
-        //    throw new NotImplementedException("MemoryCache 不支持此操作");
-        //}
-
+        #region 未实现的方法(全部补齐)
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="vals"></param>
+        /// <returns></returns>
         public Task HashSetAsync(string key, List<HashKeyValue> vals)
         {
-            throw new NotImplementedException("MemoryCache 不支持此操作");
-        }
-
-        List<HashKeyValue> IAppCache.HashGetAll(string key)
-        {
-            throw new NotImplementedException("MemoryCache 不支持此操作");
+            HashSet(key, vals);
+            return Task.CompletedTask;
         }
-
-        Task<List<HashKeyValue>> IAppCache.HashGetAllAsync(string key)
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public List<HashKeyValue> HashGetAll(string key)
         {
-            throw new NotImplementedException("MemoryCache 不支持此操作");
+            var result = new List<HashKeyValue>();
+            if (key_hash_set.TryGetValue(key, out var _hash))
+            {
+                foreach (var item in _hash) result.Add(new HashKeyValue { Key = item.Key, Value = item.Value });
+                return result;
+            }
+            if (key_hash_num.TryGetValue(key, out var _hash_num))
+            {
+                foreach (var item in _hash_num) result.Add(new HashKeyValue { Key = item.Key, Value = item.Value.ToString() });
+                return result;
+            }
+            return result;
         }
-
+        ///// <summary>
+        ///// 
+        ///// </summary>
+        ///// <param name="key"></param>
+        ///// <returns></returns>
+        //Task<List<HashKeyValue>> IAppCache.HashGetAllAsync(string key)
+        //{
+        //    return Task.FromResult(((IAppCache)this).HashGetAll(key));
+        //}
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="pattern"></param>
+        /// <param name="size"></param>
+        /// <param name="cursor"></param>
+        /// <param name="offset"></param>
+        /// <returns></returns>
         public Task<HashEntry[]> HashScanAsync(string key, string pattern, int size = 1, int cursor = 0, int offset = 0)
         {
-            throw new NotImplementedException("MemoryCache 不支持 HashScan");
+            // 简化实现:按 cursor 当 page, size 当每页大小
+            var page = cursor <= 0 ? 1 : cursor;
+            var task = HashScanAsync(key, pattern, page, size, false);
+            return Task.FromResult(task.Result.ToArray());
         }
 
         #endregion
@@ -1447,84 +1112,234 @@ namespace PasteApeart.Handler.redis
             }
         }
 
+        #endregion
+
+        #region HashIncrement(int) / ReadString / ReadObject / Set / List / SortedSet 补齐
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="felid"></param>
+        /// <param name="num"></param>
+        /// <returns></returns>
         public Task HashIncrementAsync(string key, string felid, int num = 1)
         {
-            throw new NotImplementedException();
+            var dict = key_hash_num.GetOrAdd(key, _ => new ConcurrentDictionary<string, long>());
+            var result = dict.AddOrUpdate(felid, num, (k, old) => old + num);
+            return Task.FromResult(result);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public Task<string> ReadStringAsync(string key)
         {
-            throw new NotImplementedException();
+            return Task.FromResult(Get(key));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="key"></param>
+        /// <returns></returns>
         public Task<T> ReadObjectAsync<T>(string key)
         {
-            throw new NotImplementedException();
+            return Task.FromResult(GetObject<T>(key));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <param name="val"></param>
+        /// <returns></returns>
         public Task<bool> SetAddAsync(string skey, int val)
         {
-            throw new NotImplementedException();
+            var set = key_set.GetOrAdd(skey, _ => new ConcurrentDictionary<int, byte>());
+            return Task.FromResult(set.TryAdd(val, 0));
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <param name="filed"></param>
+        /// <returns></returns>
         public Task<bool> SetContainsAsync(string skey, int filed)
         {
-            throw new NotImplementedException();
+            if (key_set.TryGetValue(skey, out var set))
+            {
+                return Task.FromResult(set.ContainsKey(filed));
+            }
+            return Task.FromResult(false);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <param name="filed"></param>
+        /// <returns></returns>
         public Task<bool> SetRemoveAsync(string skey, int filed)
         {
-            throw new NotImplementedException();
+            if (key_set.TryGetValue(skey, out var set))
+            {
+                return Task.FromResult(set.TryRemove(filed, out _));
+            }
+            return Task.FromResult(false);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <returns></returns>
         public Task<long> SetRandomMemberAsync(string skey)
         {
-            throw new NotImplementedException();
+            if (key_set.TryGetValue(skey, out var set) && set.Count > 0)
+            {
+                var keys = set.Keys.ToArray();
+                return Task.FromResult((long)keys[_random.Next(keys.Length)]);
+            }
+            return Task.FromResult(0L);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <returns></returns>
         public Task<long> SetLengthAsync(string skey)
         {
-            throw new NotImplementedException();
+            if (key_set.TryGetValue(skey, out var set))
+            {
+                return Task.FromResult((long)set.Count);
+            }
+            return Task.FromResult(0L);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <param name="sval"></param>
+        /// <returns></returns>
         public Task<long> ListRightPushAsync(string skey, string sval)
         {
-            throw new NotImplementedException();
+            lock (_listLock)
+            {
+                var list = key_list.GetOrAdd(skey, _ => new List<string>());
+                list.Add(sval);
+                return Task.FromResult((long)list.Count);
+            }
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <param name="score"></param>
+        /// <returns></returns>
         public Task<string> SortedSetRangeByScoreAsync(string skey, long score)
         {
-            throw new NotImplementedException();
+            if (key_hash_num.TryGetValue(skey, out var _hash))
+            {
+                var item = _hash.FirstOrDefault(x => x.Value == score);
+                if (item.Key != null)
+                {
+                    return Task.FromResult(item.Key);
+                }
+            }
+            return Task.FromResult(string.Empty);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <returns></returns>
         public Task<long> SortedSetRangeByRankWithScoresAsync(string skey)
         {
-            throw new NotImplementedException();
+            if (key_hash_num.TryGetValue(skey, out var _hash))
+            {
+                return Task.FromResult((long)_hash.Count);
+            }
+            return Task.FromResult(0L);
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <returns></returns>
         public Task<long> ListLengthAsync(string skey)
         {
-            throw new NotImplementedException();
+            lock (_listLock)
+            {
+                if (key_list.TryGetValue(skey, out var list))
+                {
+                    return Task.FromResult((long)list.Count);
+                }
+                return Task.FromResult(0L);
+            }
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <returns></returns>
         public Task<string> ListLeftPopAsync(string skey)
         {
-            throw new NotImplementedException();
+            lock (_listLock)
+            {
+                if (key_list.TryGetValue(skey, out var list) && list.Count > 0)
+                {
+                    var val = list[0];
+                    list.RemoveAt(0);
+                    return Task.FromResult(val);
+                }
+                return Task.FromResult(string.Empty);
+            }
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="skey"></param>
+        /// <param name="start"></param>
+        /// <param name="stop"></param>
+        /// <returns></returns>
         public Task<List<string>> ListRangeAsync(string skey, int start = 0, int stop = 30)
         {
-            throw new NotImplementedException();
+            lock (_listLock)
+            {
+                if (key_list.TryGetValue(skey, out var list))
+                {
+                    if (start < 0) start = 0;
+                    if (stop >= list.Count) stop = list.Count - 1;
+                    if (start > stop) return Task.FromResult(new List<string>());
+                    return Task.FromResult(list.GetRange(start, stop - start + 1));
+                }
+                return Task.FromResult(new List<string>());
+            }
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="skey"></param>
+        /// <param name="start"></param>
+        /// <param name="stop"></param>
+        /// <returns></returns>
         public Task<List<T>> ListRangeAsync<T>(string skey, int start = 0, int stop = 30)
         {
-            throw new NotImplementedException();
+            var strList = ListRangeAsync(skey, start, stop).Result;
+            var result = new List<T>();
+            foreach (var s in strList)
+            {
+                try
+                {
+                    result.Add(JsonSerializer.Deserialize<T>(s, JsonConfig.Options));
+                }
+                catch
+                {
+                    // 忽略反序列化失败项
+                }
+            }
+            return Task.FromResult(result);
         }
 
         #endregion
-
-
     }
-
-}
+}
\ No newline at end of file
framework/PasteApeart.Handler/redis/RedisClient.cs
diff --git a/framework/PasteApeart.Handler/redis/RedisClient.cs b/framework/PasteApeart.Handler/redis/RedisClient.cs
index 7f68d6d..a9b27d4 100644
--- a/framework/PasteApeart.Handler/redis/RedisClient.cs
+++ b/framework/PasteApeart.Handler/redis/RedisClient.cs
@@ -434,6 +434,27 @@ namespace PasteApeart.Handler.redis
             return result;
 
         }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public HashEntry[] HashGetAllEntry(string key)
+        {
+            return _database.HashGetAll(setKey(key));
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        public async Task<HashEntry[]> HashGetAllEntryAsync(string key)
+        {
+            return await _database.HashGetAllAsync(setKey(key));
+        }
+
         /// <summary>
         /// 
         /// </summary>
@@ -470,6 +491,8 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="vals"></param>
+        /// <param name="isnum"></param>
+        /// <returns></returns>
         public async Task HashSetAsync(string key, HashEntry[] vals, bool isnum = false)
         {
             await _database.HashSetAsync(setKey(key), vals);
@@ -479,12 +502,21 @@ namespace PasteApeart.Handler.redis
         /// 
         /// </summary>
         /// <param name="key"></param>
-        /// <param name="vals"></param>
+        /// <param name="field"></param>
+        /// <param name="value"></param>
+        /// <param name="isnum"></param>
+        /// <returns></returns>
         public async Task HashSetAsync(string key, string field, RedisValue value, bool isnum = false)
         {
             await _database.HashSetAsync(setKey(key), field, value);
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="sunkey"></param>
+        /// <returns></returns>
         public string HashGet(string key, string sunkey)
         {
             return _database.HashGet(setKey(key), sunkey);
@@ -495,6 +527,7 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="sunkey"></param>
+        /// <param name="isnum"></param>
         /// <returns></returns>
         public async Task<string> HashGetAsync(string key, string sunkey, bool isnum = false)
         {
@@ -503,10 +536,11 @@ namespace PasteApeart.Handler.redis
 
 
         /// <summary>
-        /// 同时获取多个
+        /// 
         /// </summary>
         /// <param name="key"></param>
-        /// <param name="sunkey"></param>
+        /// <param name="fields"></param>
+        /// <param name="isinnum"></param>
         /// <returns></returns>
         public async Task<RedisValue[]> HashGetAsync(string key, RedisValue[] fields, bool isinnum = false)
         {
@@ -529,7 +563,7 @@ namespace PasteApeart.Handler.redis
         /// 
         /// </summary>
         /// <param name="key"></param>
-        /// <param name="field"></param>
+        /// <param name="fields"></param>
         /// <returns></returns>
         public async Task<bool> HashDeleteAsync(string key, RedisValue[] fields)
         {
@@ -586,6 +620,7 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
+        /// <param name="num"></param>
         /// <returns></returns>
         public long HashIncrement(string key, string field, long num = 1)
         {
@@ -597,6 +632,7 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
+        /// <param name="val"></param>
         /// <returns></returns>
         public async Task<long> HashDecrementAsync(string key, string field, long val = 1)
         {
@@ -628,13 +664,13 @@ namespace PasteApeart.Handler.redis
         }
 
         /// <summary>
-        /// Hash 分页查询
-        /// 已测试可以使用
+        /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="pattern"></param>
-        /// <param name="page">页码从1开始</param>
-        /// <param name="size">每页的大小</param>
+        /// <param name="page"></param>
+        /// <param name="size"></param>
+        /// <param name="isincom"></param>
         /// <returns></returns>
         public async Task<List<HashEntry>> HashScanAsync(string key, string pattern, int page, int size, bool isincom = true)
         {
@@ -682,6 +718,7 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
+        /// <param name="isNum"></param>
         /// <returns></returns>
         public async Task<int> HashGetIntFieldAsync(string key, string field, bool isNum = false)
         {
@@ -693,12 +730,12 @@ namespace PasteApeart.Handler.redis
             }
             return default(int);
         }
-
         /// <summary>
         /// 
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
+        /// <param name="isNum"></param>
         /// <returns></returns>
         public async Task<long> HashGetLongFieldAsync(string key, string field, bool isNum = false)
         {
@@ -807,7 +844,6 @@ namespace PasteApeart.Handler.redis
         /// </summary>
         /// <param name="key"></param>
         /// <param name="field"></param>
-        /// <param name="value"></param>
         /// <returns></returns>
         public async Task<bool> SortedSetRemoveAsync(string key, string field)
         {
@@ -865,6 +901,11 @@ namespace PasteApeart.Handler.redis
             return await _database.StringSetBitAsync(setKey(key), offset, bit);
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="vals"></param>
         public void HashSet(string key, List<HashKeyValue> vals)
         {
             var list = new List<HashEntry>();
@@ -876,6 +917,13 @@ namespace PasteApeart.Handler.redis
             _database.HashSet(setKey(key), list.ToArray());
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="vals"></param>
+        /// <param name="isnum"></param>
+        /// <returns></returns>
         public async Task HashSetAsync(string key, List<HashKeyValue> vals, bool isnum = false)
         {
             var list = new List<HashEntry>();
@@ -887,6 +935,12 @@ namespace PasteApeart.Handler.redis
             await _database.HashSetAsync(setKey(key), list.ToArray());
         }
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="val"></param>
+        /// <returns></returns>
         public bool SetValue(string key, string val)
         {
             return Set(key, val);
@@ -999,7 +1053,12 @@ namespace PasteApeart.Handler.redis
         #endregion
 
 
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="key"></param>
+        /// <param name="vals"></param>
+        /// <returns></returns>
         public async Task HashSetAsync(string key, List<HashKeyValue> vals)
         {
             var list = new List<HashEntry>();
@@ -1050,7 +1109,6 @@ namespace PasteApeart.Handler.redis
         /// 从hash中获取随机一个!!!
         /// </summary>
         /// <param name="key"></param>
-        /// <param name="count"></param>
         /// <returns></returns>
         public async Task<HashEntry> HashRandomFieldsWithValuesAsync(string key)
         {
@@ -1063,11 +1121,13 @@ namespace PasteApeart.Handler.redis
         }
 
         /// <summary>
-        /// 查询符合条件的
+        /// 
         /// </summary>
         /// <param name="key"></param>
-        /// <param name="pattern">*XXX*</param>
+        /// <param name="pattern"></param>
         /// <param name="size"></param>
+        /// <param name="cursor"></param>
+        /// <param name="offset"></param>
         /// <returns></returns>
         public async Task<HashEntry[]> HashScanAsync(string key, string pattern, int size = 1, int cursor = 0, int offset = 0)
         {
framework/PasteApeart.Helper/BuilderHelper.cs
diff --git a/framework/PasteApeart.Helper/BuilderHelper.cs b/framework/PasteApeart.Helper/BuilderHelper.cs
index 464eb63..377c7b5 100644
--- a/framework/PasteApeart.Helper/BuilderHelper.cs
+++ b/framework/PasteApeart.Helper/BuilderHelper.cs
@@ -1105,6 +1105,21 @@ namespace PasteApeart.Helper
                             }
                         }
                     }
+
+                    // 判断是否为基础类型数组(如 int[]、string[] 等),是则追加特性split
+                    var _ele_type = _property.PropertyType.GetElementType();
+                    if (_property.PropertyType.IsArray && _ele_type != null && _ele_type.FullName != null && _ele_type.FullName.StartsWith("System"))
+                    {
+                        if (proInfo.Attributes == null)
+                        {
+                            proInfo.Attributes = new List<VoloModelAttribute>();
+                        }
+                        if (!proInfo.Attributes.Any(x => x.Name == "split"))
+                        {
+                            proInfo.Attributes.Add(new VoloModelAttribute { Name = "split", Args1 = ";" });
+                        }
+                    }
+
                 }
 
                 //有Description特性的话,如果是空值,可能是故意这么设定的!
framework/PasteApeart.Helper/readme.md
diff --git a/framework/PasteApeart.Helper/readme.md b/framework/PasteApeart.Helper/readme.md
index fbe76c8..08564dd 100644
--- a/framework/PasteApeart.Helper/readme.md
+++ b/framework/PasteApeart.Helper/readme.md
@@ -1,6 +1,10 @@
 
 # 贴代码框架PasteApeart简介
 
+## 26.10.03
+	1.如果是string[] int[]等,在表单的时候,追加一个split(;)的特性,这样对于form就可以编辑了!
+
+
 ## 26.09.21
 	1.Enum的0全部字段,支持不同i形态,比如全部/无 那么在搜索区域显示的是全部,在表单或者表格则是无
 
manage/page/pasteform/index.html
diff --git a/manage/page/pasteform/index.html b/manage/page/pasteform/index.html
index cc793bd..ffaab9c 100644
--- a/manage/page/pasteform/index.html
+++ b/manage/page/pasteform/index.html
@@ -22,7 +22,7 @@
 
     <div class="page-container index-page">
         <div class="searcharea">
-            <form id="formsearch" class="pasteform oneline"  onsubmit="return false;" action="javascript:void(0);">
+            <form id="formsearch" class="pasteform oneline" onsubmit="return false;" action="javascript:void(0);">
                 <div class="searchbox"></div>
             </form>
             <div class="tap_more">
@@ -32,7 +32,7 @@
         </div>
         <div class="ppbody">
             <div class="st">
-                
+
                 <input type="button" class="isedit btn btnstyle btnadd" value="新增" onclick="tap_add_form(this);" />
 
                 <!-- 用于显示表名或者是模块名称 -->
@@ -44,24 +44,28 @@
                 <div class="func_btn_area"></div>
 
                 <!-- 切换table和chart模式 -->
-                 <div class="show_type">
-                    <i class="Hui-iconfont Hui-iconfont-zhongtumoshi type_table rbtn selected" onclick="handlerChangeShowType(false,this);"></i>
-                    <i class="Hui-iconfont Hui-iconfont-tongji-xian type_chart rbtn" onclick="handlerChangeShowType(true,this);"></i>
-                 </div>
-
+                <div class="show_type">
+                    <i class="Hui-iconfont Hui-iconfont-zhongtumoshi type_table rbtn selected"
+                        onclick="handlerChangeShowType(false,this);"></i>
+                    <i class="Hui-iconfont Hui-iconfont-tongji-xian type_chart rbtn"
+                        onclick="handlerChangeShowType(true,this);"></i>
+                </div>
+                <a href="javascript:exportExcel(this);" style="display:none;" class="btnautoarea command_excel_out" title="导出当前页为EXCEL"><i
+                        class="Hui-iconfont Hui-iconfont-dangan"></i></a>
                 <input type="button" class="btnsearch btn" onclick="readPageData(1);" value="查询">
                 <a class="btnrefush" href="javascript:location.replace(location.href);" title="刷新"><i
                         class="Hui-iconfont">&#xe68f;</i></a>
                 <a href="javascript:func_auto_searcharea(this);" class="btnautoarea" title="显示更多查询项"><i
                         class="Hui-iconfont Hui-iconfont-search1"></i></a>
-                        <a href="javascript:printTable(this);" class="btnautoarea" title="打印当前页,建议使用横向模式"><i
-                            class="Hui-iconfont Hui-iconfont-dayinji"></i></a>
-                            <a href="javascript:cleanTableColumnOrder(this);" class="btnautoarea btn_clear_order_column" title="清理列排序缓存"><i
-                                class="Hui-iconfont Hui-iconfont-del2"></i></a>
+                <a href="javascript:printTable(this);" class="btnautoarea command_print" title="打印当前页,建议使用横向模式"><i
+                        class="Hui-iconfont Hui-iconfont-dayinji"></i></a>
+                <a href="javascript:cleanTableColumnOrder(this);" class="btnautoarea btn_clear_order_column"
+                    title="清理列排序缓存"><i class="Hui-iconfont Hui-iconfont-del2"></i></a>
             </div>
             <div class="batcharea"></div>
             <div class="mt-20 table_wrap">
-                <table id="data-table" class="table table-border table-bordered tb_freeze table-bg table-hover table-sort table-responsive">
+                <table id="data-table"
+                    class="table table-border table-bordered tb_freeze table-bg table-hover table-sort table-responsive">
                     <thead>
                     </thead>
                     <tbody>
@@ -251,7 +255,7 @@
                     </div>
                 <% } %>
             <% }) %>
-        </script>    
+        </script>
 
 
         <!-- 头部的批量操作的模板 -->
@@ -505,12 +509,12 @@
                 <% } %>
             </tr>
         </script>
-        <!-- 版本二 --> 
+        <!-- 版本二 -->
         <script type="text/html" id="template_body_tbody">
             <!-- 注意花括号百分比的是当前的模板 2个花括号的是占位,下一个的模板代码 -->
-            <% list.forEach(ii=>{ %>
-                <%:=templatetr({item:ii,config:config}) %>
-            <% }) %>
+        <% list.forEach(ii=>{ %>
+            <%:=templatetr({item:ii,config:config}) %>
+                <% }) %>
         </script>
 
         <!-- 生成后的模板内容,用于排错用 -->
@@ -526,7 +530,7 @@
     <script type="text/javascript" src="./lib/template.js"></script>
     <script type="text/javascript" src="./lib/My97DatePicker/4.8/WdatePicker.js"></script>
     <script type="text/javascript" src="../lib/api.js?v=251002"></script>
-    
+
     <!-- <script type="text/javascript" src="../lib/page.min.js"></script> -->
 
     <script type="text/javascript" src="../lib/jquery.pagination.js"></script>
manage/page/pasteform/index.js
diff --git a/manage/page/pasteform/index.js b/manage/page/pasteform/index.js
index 46a22a7..ec90d06 100644
--- a/manage/page/pasteform/index.js
+++ b/manage/page/pasteform/index.js
@@ -79,6 +79,7 @@ var _config = {
     search_after_selected: true,//搜索区域outer选择后,是否直接查询
     trclass: null,//表格中trclass的字段名称,实际中这个值中去获取
     batch: false,//是否启用批量操作
+    show_excel:false,//是否启用导出excel功能
     orderby:"id",//排序
     update_row_min_match_rate: 0.6,//更新行数据的时候,最小匹配率,低于这个值则不进行更新
     bind_with_edit: false,//绑定模式下,是否启用编辑模式
@@ -185,6 +186,13 @@ $(window).ready(function () {
     addImgTapListenter();
 
     QueryModel();
+
+    //显示导出功能
+    if(_config.show_excel){
+        $(".command_excel_out").show();
+        //载入资源组件 导出到excel
+        loadResource("./lib/xlsx.js",false);
+    }
 });
 
 /**
manage/page/pasteform/lib/xlsx.js
diff --git a/manage/page/pasteform/lib/xlsx.js b/manage/page/pasteform/lib/xlsx.js
new file mode 100644
index 0000000..dc3eb01
--- /dev/null
+++ b/manage/page/pasteform/lib/xlsx.js
@@ -0,0 +1,177 @@
+// expend.js
+// window._global_list_properties
+// window.global_page_data
+// window._global_list_properties
+// window.global_page_data
+(function () {
+
+    // 保存原始函数引用
+    const oldPageLoad = window.afterReadPageData;
+
+    // console.log(oldPageLoad, 'oldPageLoad');
+
+    // 闭包内缓存当前页面数据,避免跨页面数据污染
+    var pageDataCache = null;
+
+    window.afterReadPageData = function (code, obj, page) {
+        if (obj && Array.isArray(obj)) {
+            pageDataCache = obj;
+        } else if (obj && typeof obj === 'object' && obj.items && Array.isArray(obj.items)) {
+            pageDataCache = obj.items;
+        }
+
+        let result;
+        if (oldPageLoad) {
+            result = oldPageLoad.call(this, code, obj, page);
+        }
+        return result;
+    };
+
+    // HTML转纯文本
+    function htmlToText(html) {
+        if (html === null || html === undefined) return '';
+        if (typeof html !== 'string') return String(html);
+        // 处理<br>和<br/>换行
+        let text = html.replace(/<br\s*\/?>/gi, '\n');
+        // 处理</span>、</div>等块级元素闭合标签后加换行
+        text = text.replace(/<\/(span|div|p|li|tr)>/gi, function (match, tag) {
+            return tag === 'span' ? ' ' : '\n';
+        });
+        // 去除所有HTML标签
+        text = text.replace(/<[^>]+>/g, '');
+        // 解码HTML实体
+        text = text.replace(/&amp;/g, '&')
+                   .replace(/&lt;/g, '<')
+                   .replace(/&gt;/g, '>')
+                   .replace(/&quot;/g, '"')
+                   .replace(/&#39;/g, "'")
+                   .replace(/&nbsp;/g, ' ');
+        // 清理多余空白
+        text = text.replace(/[ \t]+/g, ' ').trim();
+        return text;
+    }
+
+    // 获取单元格的值,处理对象和HTML
+    function getCellValue(value) {
+        if (value === null || value === undefined) return '';
+        // 对象类型取name属性(如 extendSubject: {id: 11, name: "财聚天下"})
+        if (typeof value === 'object') {
+          if (value.name !== undefined) return value.name;
+          if (value.id !== undefined) return value.id;
+          return JSON.stringify(value);
+        }
+        // 字符串类型检查是否包含HTML标签
+        if (typeof value === 'string' && /<[a-zA-Z][^>]*>/.test(value)) {
+          return htmlToText(value);
+        }
+        return String(value);
+    }
+
+    // 导出Excel
+    function exportExcel() {
+        var properties = window._global_list_properties;
+        var cache = pageDataCache;
+        // console.log(properties, 'properties');
+        
+        if (!properties || !Array.isArray(properties) || properties.length === 0) {
+          console.warn('导出Excel: 未找到表头配置 _global_list_properties');
+          return;
+        }
+        if (!cache || !Array.isArray(cache) || cache.length === 0) {
+          console.warn('导出Excel: 未找到数据 _pageDataCache');
+          return;
+        }
+
+        // 获取数据列表
+        var items = cache;
+        // 如果缓存的是分页对象,取items
+        if (cache.items && Array.isArray(cache.items)) {
+          items = cache.items;
+        }
+
+        // 过滤隐藏列,构建表头
+        // ★ 过滤 attributes 含 outignore / ifmenu 的列(操作按钮、忽略导出类字段)
+        var visibleProps = properties.filter(function (p) {
+          if(p.name == p.title) return false;
+          if (!p.attributes || !Array.isArray(p.attributes) || !p.attributes.length) return true;
+          return !p.attributes.some(function (a) {
+            return a.name === 'outignore' || a.name === 'ifmenu' || a.name === 'menuhtml' ;
+          });
+        });
+
+        var headers = visibleProps.map(function (p) {
+          return p.title || p.name || '';
+        });
+
+        var keys = visibleProps.map(function (p) {
+          return p.name;
+        });
+
+        // console.log('★ headers:', headers, '| keys:', keys);
+
+        // 构建HTML表格
+        var html = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">';
+        html += '<head><meta charset="UTF-8">';
+        html += '<!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>Sheet1</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->';
+        html += '<style>td{mso-number-format:"\\@";}</style>';
+        html += '</head><body>';
+        html += '<table border="1">';
+
+        // 表头行(用<td>+内联样式,Excel兼容性更好)
+        html += '<tr>';
+        headers.forEach(function (h) {
+          html += '<td style="background:#4472C4;color:#fff;font-weight:bold;text-align:center;">' + h + '</td>';
+        });
+        html += '</tr>';
+
+        // console.log('★ 表头HTML:', html); // 验证表头是否写入
+
+        // 数据行
+        items.forEach(function (row) {
+          html += '<tr>';
+          keys.forEach(function (key) {
+            var val = '';
+            // 处理嵌套字段(如 extendBusinessModel?.name)
+            if (key.indexOf('?.') !== -1) {
+              var parts = key.split('?.');
+              var cur = row;
+              for (var pi = 0; pi < parts.length; pi++) {
+                if (cur == null || typeof cur !== 'object') { cur = undefined; break; }
+                cur = cur[parts[pi]];
+              }
+              val = getCellValue(cur);
+            } else {
+              val = getCellValue(row[key]);
+            }
+            html += '<td>' + val + '</td>';
+          });
+          html += '</tr>';
+        });
+
+        html += '</table></body></html>';
+
+        // 生成Blob并下载
+        var blob = new Blob([html], { type: 'application/vnd.ms-excel;charset=utf-8' });
+        var url = URL.createObjectURL(blob);
+        var link = document.createElement('a');
+        link.href = url;
+
+        // 生成文件名:列表数据_日期
+        var now = new Date();
+        var dateStr = now.getFullYear() + '-' +
+          String(now.getMonth() + 1).padStart(2, '0') + '-' +
+          String(now.getDate()).padStart(2, '0') + ' ' +
+          String(now.getHours()).padStart(2, '0') + ':' +
+          String(now.getMinutes()).padStart(2, '0');
+        link.download = '列表数据_' + dateStr + '.xls';
+
+        document.body.appendChild(link);
+        link.click();
+        document.body.removeChild(link);
+        URL.revokeObjectURL(url);
+    }
+
+    // 暴露到全局,外部可直接调用
+    window.exportExcel = exportExcel;
+
+})();
\ No newline at end of file
​ ​