mirror of
				https://gitee.com/ThingsGateway/ThingsGateway.git
				synced 2025-10-31 23:53:58 +08:00 
			
		
		
		
	Compare commits
	
		
			29 Commits
		
	
	
		
			10.11.83.0
			...
			variablePa
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 2f58f7b47c | ||
|   | 576c5207b7 | ||
|   | 2e83c19e0c | ||
|   | b22e90609b | ||
|   | 35edd7dc43 | ||
|   | bd178831e3 | ||
|   | fe9ec6ad10 | ||
|   | 67354e70b3 | ||
|   | 6f9ec2e24b | ||
|   | c0337e2b19 | ||
|   | 8a95f48f5a | ||
|   | 14f3c31265 | ||
|   | 1bad65378f | ||
|   | db3affc67e | ||
|   | 5ee8b50a92 | ||
|   | 301beda2a2 | ||
|   | 628b51a353 | ||
|   | f03445bc83 | ||
|   | 55a2ff5487 | ||
|   | 0fef7dcf3b | ||
|   | 19d9702606 | ||
|   | a8a9774932 | ||
|   | aad0f0e8c3 | ||
|   | e74eae50a7 | ||
|   | 3b16d7019f | ||
|   | 3e038028c2 | ||
|   | b1d8041f7e | ||
|   | 53a98b26cd | ||
|   | 42c740fa1b | 
| @@ -251,11 +251,13 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter | ||||
|  | ||||
|         if (exception == null) | ||||
|         { | ||||
|             logger.Log(LogLevel.Information, $"{logData.Method}:{logData.Path}-{logData.Operation}"); | ||||
|             if (logger.IsEnabled(LogLevel.Information)) | ||||
|                 logger.Log(LogLevel.Information, $"{logData.Method}:{logData.Path}-{logData.Operation}"); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             logger.Log(LogLevel.Warning, $"{logData.Method}:{logData.Path}-{logData.Operation}{Environment.NewLine}{logData.Exception?.ToSystemTextJsonString()}{Environment.NewLine}{logData.Validation?.ToSystemTextJsonString()}"); | ||||
|             if (logger.IsEnabled(LogLevel.Warning)) | ||||
|                 logger.Log(LogLevel.Warning, $"{logData.Method}:{logData.Path}-{logData.Operation}{Environment.NewLine}{logData.Exception?.ToSystemTextJsonString()}{Environment.NewLine}{logData.Validation?.ToSystemTextJsonString()}"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -20,7 +20,7 @@ namespace ThingsGateway.Admin.Application; | ||||
| /// <typeparam name="TEntry"></typeparam> | ||||
| public class EventService<TEntry> : IEventService<TEntry>, IDisposable | ||||
| { | ||||
|     private ConcurrentDictionary<string, Func<TEntry, Task>> Cache = new(); | ||||
|     private NonBlockingDictionary<string, Func<TEntry, Task>> Cache = new(); | ||||
|  | ||||
|     public void Dispose() | ||||
|     { | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| 	 | ||||
| 	<ItemGroup> | ||||
| 		<PackageReference Include="Riok.Mapperly" Version="4.2.1" ExcludeAssets="runtime" PrivateAssets="all" /> | ||||
| 		<PackageReference Include="Rougamo.Fody" Version="5.0.1" /> | ||||
| 		<PackageReference Include="Rougamo.Fody" Version="5.0.2" /> | ||||
| 	</ItemGroup> | ||||
| 	<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' "> | ||||
| 		<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" /> | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
|  | ||||
| <div class="tg-table h-100"> | ||||
|  | ||||
|     <Table TItem="TItem" IsBordered="true" IsStriped="true" TableSize="TableSize.Compact" SelectedRows=SelectedRows SelectedRowsChanged=privateSelectedRowsChanged IsMultipleSelect="IsMultipleSelect" @ref="Instance" SearchTemplate="SearchTemplate" | ||||
|            DataService="DataService" CreateItemCallback="CreateItemCallback!" | ||||
|     <Table Id=@Id TItem="TItem" IsBordered="true" IsStriped="true" TableSize="TableSize.Compact" SelectedRows=SelectedRows SelectedRowsChanged=privateSelectedRowsChanged IsMultipleSelect="IsMultipleSelect" @ref="Instance" SearchTemplate="SearchTemplate" | ||||
|            DataService="DataService" CreateItemCallback="CreateItemCallback!" RenderMode=RenderMode OnColumnCreating=OnColumnCreating | ||||
|            IsPagination="IsPagination" PageItemsSource="PageItemsSource" IsFixedHeader="IsFixedHeader" IndentSize=24 RowHeight=RowHeight ShowSearchText="ShowSearchText" ShowSearchButton="ShowSearchButton" DisableEditButtonCallback="DisableEditButtonCallback" DisableDeleteButtonCallback="DisableDeleteButtonCallback" BeforeShowEditDialogCallback=" BeforeShowEditDialogCallback!" | ||||
|            IsTree="IsTree" OnTreeExpand="OnTreeExpand!" TreeNodeConverter="TreeNodeConverter!" TreeIcon="fa-solid fa-circle-chevron-right" TreeExpandIcon="fa-solid fa-circle-chevron-right fa-rotate-90" IsAutoQueryFirstRender=IsAutoQueryFirstRender | ||||
|            ShowDefaultButtons="ShowDefaultButtons" ShowAdvancedSearch="ShowAdvancedSearch" ShowResetButton=ShowResetButton | ||||
| @@ -14,7 +14,7 @@ | ||||
|            ShowSkeleton="true" ShowLoading="ShowLoading" ShowSearch="ShowSearch" SearchModel=@SearchModel ShowLineNo | ||||
|            SearchMode=SearchMode ShowExportPdfButton=ShowExportPdfButton ExportButtonText=@ExportButtonText | ||||
|            ShowExportButton=@ShowExportButton Items=Items ClickToSelect=ClickToSelect ScrollMode=ScrollMode | ||||
|            ShowExportCsvButton=@ShowExportCsvButton ShowCardView=ShowCardView | ||||
|            ShowExportCsvButton=@ShowExportCsvButton ShowCardView=ShowCardView OnColumnVisibleChanged=OnColumnVisibleChanged | ||||
|            FixedExtendButtonsColumn=FixedExtendButtonsColumn FixedMultipleColumn=FixedMultipleColumn FixedDetailRowHeaderColumn=FixedDetailRowHeaderColumn FixedLineNoColumn=FixedLineNoColumn | ||||
|            IsAutoRefresh=IsAutoRefresh AutoRefreshInterval=AutoRefreshInterval | ||||
|            AllowDragColumn=@AllowDragColumn Height=@Height ShowRefresh=ShowRefresh | ||||
| @@ -41,6 +41,7 @@ | ||||
|            DoubleClickToEdit="DoubleClickToEdit" | ||||
|            OnDoubleClickCellCallback="OnDoubleClickCellCallback" | ||||
|            OnDoubleClickRowCallback="OnDoubleClickRowCallback" | ||||
|            RowContentTemplate="RowContentTemplate" | ||||
|            OnClickRowCallback="OnClickRowCallback"> | ||||
|     </Table> | ||||
| </div> | ||||
|   | ||||
| @@ -13,6 +13,23 @@ namespace ThingsGateway.Admin.Razor; | ||||
| [CascadingTypeParameter(nameof(TItem))] | ||||
| public partial class AdminTable<TItem> where TItem : class, new() | ||||
| { | ||||
|     /// <inheritdoc cref="Table{TItem}.OnColumnVisibleChanged"/> | ||||
|     [Parameter] | ||||
|     public Func<string,bool, Task> OnColumnVisibleChanged { get; set; } | ||||
|  | ||||
|     /// <inheritdoc cref="Table{TItem}.OnColumnCreating"/> | ||||
|     [Parameter] | ||||
|     public Func<List<ITableColumn>,Task> OnColumnCreating { get; set; } | ||||
|     /// <inheritdoc cref="Table{TItem}.RenderMode"/> | ||||
|     [Parameter] | ||||
|     public TableRenderMode RenderMode { get; set; } | ||||
|  | ||||
|     public List<ITableColumn> Columns => Instance?.Columns; | ||||
|  | ||||
|     public IEnumerable<ITableColumn> GetVisibleColumns => Instance?.GetVisibleColumns(); | ||||
|     public List<TItem> Rows => Instance?.Rows; | ||||
|  | ||||
|  | ||||
|     /// <inheritdoc cref="Table{TItem}.SelectedRowsChanged"/> | ||||
|     [Parameter] | ||||
|     public EventCallback<List<TItem>> SelectedRowsChanged { get; set; } | ||||
| @@ -40,6 +57,10 @@ public partial class AdminTable<TItem> where TItem : class, new() | ||||
|     /// <inheritdoc cref="Table{TItem}.OnDoubleClickRowCallback"/> | ||||
|     [Parameter] | ||||
|     public Func<TItem, Task>? OnDoubleClickRowCallback { get; set; } | ||||
|     /// <inheritdoc cref="Table{TItem}.RowContentTemplate"/> | ||||
|     [Parameter] | ||||
|     public RenderFragment<TableRowContext<TItem>>? RowContentTemplate { get; set; } | ||||
|  | ||||
|     /// <inheritdoc cref="Table{TItem}.OnClickRowCallback"/> | ||||
|     [Parameter] | ||||
|     public Func<TItem, Task>? OnClickRowCallback { get; set; } | ||||
| @@ -146,6 +167,9 @@ public partial class AdminTable<TItem> where TItem : class, new() | ||||
|     [Parameter] | ||||
|     public IDataService<TItem> DataService { get; set; } | ||||
|  | ||||
|     [Parameter] | ||||
|     public string? Id { get; set; } | ||||
|  | ||||
|     /// <inheritdoc cref="Table{TItem}.CreateItemCallback"/> | ||||
|     [Parameter] | ||||
|     public Func<TItem> CreateItemCallback { get; set; } | ||||
|   | ||||
| @@ -72,7 +72,7 @@ public partial class HardwareInfoPage : IDisposable | ||||
|             ChartDataSource.Options.Title = Localizer[nameof(HistoryHardwareInfo)]; | ||||
|             ChartDataSource.Options.X.Title = Localizer["DateTime"]; | ||||
|             ChartDataSource.Options.Y.Title = Localizer["Data"]; | ||||
|             ChartDataSource.Labels = hisHardwareInfos.Select(a => a.Date.ToString("dd HH:mm zz")); | ||||
|             ChartDataSource.Labels = hisHardwareInfos.Select(a => a.Date.ToString("dd-HH:mm")); | ||||
|             ChartDataSource.Data.Add(new ChartDataset() | ||||
|             { | ||||
|                 Tension = 0.4f, | ||||
| @@ -116,7 +116,7 @@ public partial class HardwareInfoPage : IDisposable | ||||
|         else | ||||
|         { | ||||
|             var hisHardwareInfos = await HardwareJob.GetHistoryHardwareInfos(); | ||||
|             ChartDataSource.Labels = hisHardwareInfos.Select(a => a.Date.ToString("dd HH:mm zz")); | ||||
|             ChartDataSource.Labels = hisHardwareInfos.Select(a => a.Date.ToString("dd-HH:mm")); | ||||
|             ChartDataSource.Data[0].Data = hisHardwareInfos.Select(a => (object)a.CpuUsage); | ||||
|             ChartDataSource.Data[1].Data = hisHardwareInfos.Select(a => (object)a.MemoryUsage); | ||||
|             ChartDataSource.Data[2].Data = hisHardwareInfos.Select(a => (object)a.DriveUsage); | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<ProjectReference Include="..\ThingsGateway.Admin.Application\ThingsGateway.Admin.Application.csproj" /> | ||||
| 		<PackageReference Include="BootstrapBlazor.Chart" Version="9.0.1" /> | ||||
| 		<PackageReference Include="BootstrapBlazor.Chart" Version="9.0.3" /> | ||||
| 		<PackageReference Include="BootstrapBlazor.UniverSheet" Version="9.0.5" /> | ||||
| 		<PackageReference Include="BootstrapBlazor.WinBox" Version="9.0.7" /> | ||||
| 		<PackageReference Include="BootstrapBlazor.CodeEditor" Version="9.0.3" /> | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| //------------------------------------------------------------------------------ | ||||
| //------------------------------------------------------------------------------ | ||||
| //  此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充 | ||||
| //  此代码版权(除特别声明外的代码)归作者本人Diego所有 | ||||
| //  源代码使用协议遵循本仓库的开源协议及附加协议 | ||||
| @@ -477,7 +477,7 @@ public class ConcurrentList<T> : IList<T>, IReadOnlyList<T> | ||||
|     { | ||||
|         lock (((ICollection)m_list).SyncRoot) | ||||
|         { | ||||
|             return m_list.IndexOf(item); | ||||
|             return m_list.LastIndexOf(item); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -16,6 +16,8 @@ using System.Runtime.CompilerServices; | ||||
| using System.Text.Json; | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.Common.Extension; | ||||
| /// <summary> | ||||
| /// 对象拓展类 | ||||
| @@ -48,113 +50,7 @@ public static class ObjectExtensions | ||||
|         bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将 DateTimeOffset 转换成本地 DateTime | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <returns></returns> | ||||
|     public static DateTime ConvertToDateTime(this DateTimeOffset dateTime) | ||||
|     { | ||||
|         if (dateTime.Offset.Equals(TimeSpan.Zero)) | ||||
|             return dateTime.UtcDateTime; | ||||
|         if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) | ||||
|             return dateTime.ToLocalTime().DateTime; | ||||
|         else | ||||
|             return dateTime.DateTime; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将 DateTimeOffset? 转换成本地 DateTime? | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <returns></returns> | ||||
|     public static DateTime? ConvertToDateTime(this DateTimeOffset? dateTime) | ||||
|     { | ||||
|         return dateTime.HasValue ? dateTime.Value.ConvertToDateTime() : null; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将 DateTime 转换成 DateTimeOffset | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <returns></returns> | ||||
|     public static DateTimeOffset ConvertToDateTimeOffset(this DateTime dateTime) | ||||
|     { | ||||
|         return DateTime.SpecifyKind(dateTime, DateTimeKind.Local); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将 DateTime? 转换成 DateTimeOffset? | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <returns></returns> | ||||
|     public static DateTimeOffset? ConvertToDateTimeOffset(this DateTime? dateTime) | ||||
|     { | ||||
|         return dateTime.HasValue ? dateTime.Value.ConvertToDateTimeOffset() : null; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将流保存到本地磁盘 | ||||
|     /// </summary> | ||||
|     /// <param name="stream"></param> | ||||
|     /// <param name="path"></param> | ||||
|     /// <returns></returns> | ||||
|     public static void CopyToSave(this Stream stream, string path) | ||||
|     { | ||||
|         // 空检查 | ||||
|         if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path)); | ||||
|  | ||||
|         using var fileStream = File.Create(path); | ||||
|         stream.CopyTo(fileStream); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将字节数组保存到本地磁盘 | ||||
|     /// </summary> | ||||
|     /// <param name="bytes"></param> | ||||
|     /// <param name="path"></param> | ||||
|     /// <returns></returns> | ||||
|     public static void CopyToSave(this byte[] bytes, string path) | ||||
|     { | ||||
|         using var stream = new MemoryStream(bytes); | ||||
|         stream.CopyToSave(path); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将流保存到本地磁盘 | ||||
|     /// </summary> | ||||
|     /// <param name="stream"></param> | ||||
|     /// <param name="path">需包含文件名完整路径</param> | ||||
|     /// <returns></returns> | ||||
|     public static async Task CopyToSaveAsync(this Stream stream, string path) | ||||
|     { | ||||
|         // 空检查 | ||||
|         if (string.IsNullOrWhiteSpace(path)) | ||||
|         { | ||||
|             throw new ArgumentNullException(nameof(path)); | ||||
|         } | ||||
|  | ||||
|         // 文件名判断 | ||||
|         if (string.IsNullOrWhiteSpace(Path.GetFileName(path))) | ||||
|         { | ||||
|             throw new ArgumentException("The parameter of <path> parameter must include the complete file name."); | ||||
|         } | ||||
|  | ||||
|         using var fileStream = File.Create(path); | ||||
|         await stream.CopyToAsync(fileStream).ConfigureAwait(false); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将字节数组保存到本地磁盘 | ||||
|     /// </summary> | ||||
|     /// <param name="bytes"></param> | ||||
|     /// <param name="path"></param> | ||||
|     /// <returns></returns> | ||||
|     public static async Task CopyToSaveAsync(this byte[] bytes, string path) | ||||
|     { | ||||
|         using var stream = new MemoryStream(bytes); | ||||
|         await stream.CopyToSaveAsync(path).ConfigureAwait(false); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 合并两个字典 | ||||
| @@ -186,7 +82,7 @@ public static class ObjectExtensions | ||||
|     /// <typeparam name="T"></typeparam> | ||||
|     /// <param name="dic">字典</param> | ||||
|     /// <param name="newDic">新字典</param> | ||||
|     internal static void AddOrUpdate<T>(this ConcurrentDictionary<string, T> dic, Dictionary<string, T> newDic) | ||||
|     internal static void AddOrUpdate<T>(this NonBlockingDictionary<string, T> dic, Dictionary<string, T> newDic) | ||||
|     { | ||||
|         foreach (var (key, value) in newDic) | ||||
|         { | ||||
|   | ||||
| @@ -66,7 +66,8 @@ internal class JsonStringLocalizer(Assembly assembly, string typeName, string ba | ||||
|                 } | ||||
|                 catch (Exception ex) | ||||
|                 { | ||||
|                     Logger.LogError(ex, "{JsonStringLocalizerName} searched for '{Name}' in '{typeName}' with culture '{CultureName}' throw exception.", nameof(JsonStringLocalizer), name, typeName, CultureInfo.CurrentUICulture.Name); | ||||
|                     if (Logger?.IsEnabled(LogLevel.Error) == true) | ||||
|                         Logger.LogError(ex, "{JsonStringLocalizerName} searched for '{Name}' in '{typeName}' with culture '{CultureName}' throw exception.", nameof(JsonStringLocalizer), name, typeName, CultureInfo.CurrentUICulture.Name); | ||||
|                 } | ||||
|                 return ret; | ||||
|             } | ||||
| @@ -176,7 +177,8 @@ internal class JsonStringLocalizer(Assembly assembly, string typeName, string ba | ||||
|         localizationMissingItemHandler.HandleMissingItem(name, typeName, CultureInfo.CurrentUICulture.Name); | ||||
|         if (jsonLocalizationOptions.IgnoreLocalizerMissing == false) | ||||
|         { | ||||
|             Logger.LogInformation("{JsonStringLocalizerName} searched for '{Name}' in '{TypeName}' with culture '{CultureName}' not found.", nameof(JsonStringLocalizer), name, typeName, CultureInfo.CurrentUICulture.Name); | ||||
|             if (Logger?.IsEnabled(LogLevel.Information) == true) | ||||
|                 Logger.LogInformation("{JsonStringLocalizerName} searched for '{Name}' in '{TypeName}' with culture '{CultureName}' not found.", nameof(JsonStringLocalizer), name, typeName, CultureInfo.CurrentUICulture.Name); | ||||
|         } | ||||
|         _missingManifestCache.TryAdd($"name={name}&culture={CultureInfo.CurrentUICulture.Name}"); | ||||
|     } | ||||
|   | ||||
| @@ -12,9 +12,9 @@ | ||||
| 	</PropertyGroup> | ||||
| 	 | ||||
| 	<ItemGroup> | ||||
| 		<PackageReference Include="BootstrapBlazor.TableExport" Version="9.2.6" /> | ||||
| 		<PackageReference Include="BootstrapBlazor.TableExport" Version="9.2.7" /> | ||||
| 		<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" /> | ||||
| 		<PackageReference Include="BootstrapBlazor" Version="9.11.0" /> | ||||
| 		<PackageReference Include="BootstrapBlazor" Version="9.11.2" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
| 	<ItemGroup> | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
|  | ||||
| using ThingsGateway; | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Reflection; | ||||
|  | ||||
| namespace Microsoft.Extensions.Hosting; | ||||
|   | ||||
| @@ -20,7 +20,7 @@ using System.Text.RegularExpressions; | ||||
|  | ||||
| using ThingsGateway.NewLife; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| /// 对象拓展类 | ||||
| @@ -28,70 +28,10 @@ namespace ThingsGateway.Extensions; | ||||
| [SuppressSniffer] | ||||
| public static class ObjectExtensions | ||||
| { | ||||
|     /// <summary> | ||||
|     /// 将 DateTimeOffset 转换成本地 DateTime | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <returns></returns> | ||||
|     public static DateTime ConvertToDateTime(this DateTimeOffset dateTime) | ||||
|     { | ||||
|         if (dateTime.Offset.Equals(TimeSpan.Zero)) | ||||
|             return dateTime.UtcDateTime; | ||||
|         if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) | ||||
|             return dateTime.ToLocalTime().DateTime; | ||||
|         else | ||||
|             return dateTime.DateTime; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将 DateTimeOffset? 转换成本地 DateTime? | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <returns></returns> | ||||
|     public static DateTime? ConvertToDateTime(this DateTimeOffset? dateTime) | ||||
|     { | ||||
|         return dateTime.HasValue ? dateTime.Value.ConvertToDateTime() : null; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将 DateTime 转换成 DateTimeOffset | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <returns></returns> | ||||
|     public static DateTimeOffset ConvertToDateTimeOffset(this DateTime dateTime) | ||||
|     { | ||||
|         return DateTime.SpecifyKind(dateTime, DateTimeKind.Local); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将 DateTime? 转换成 DateTimeOffset? | ||||
|     /// </summary> | ||||
|     /// <param name="dateTime"></param> | ||||
|     /// <returns></returns> | ||||
|     public static DateTimeOffset? ConvertToDateTimeOffset(this DateTime? dateTime) | ||||
|     { | ||||
|         return dateTime.HasValue ? dateTime.Value.ConvertToDateTimeOffset() : null; | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将时间戳转换为 DateTime | ||||
|     /// </summary> | ||||
|     /// <param name="timestamp"></param> | ||||
|     /// <returns></returns> | ||||
|     internal static DateTime ConvertToDateTime(this long timestamp) | ||||
|     { | ||||
|         var timeStampDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); | ||||
|         var digitCount = (int)Math.Floor(Math.Log10(timestamp) + 1); | ||||
|  | ||||
|         if (digitCount != 13 && digitCount != 10) | ||||
|         { | ||||
|             throw new ArgumentException("Data is not a valid timestamp format."); | ||||
|         } | ||||
|  | ||||
|         return (digitCount == 13 | ||||
|             ? timeStampDateTime.AddMilliseconds(timestamp)  // 13 位时间戳 | ||||
|             : timeStampDateTime.AddSeconds(timestamp)).ToLocalTime();   // 10 位时间戳 | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 将 IFormFile 转换成 byte[] | ||||
| @@ -265,7 +205,7 @@ public static class ObjectExtensions | ||||
|     /// <typeparam name="T"></typeparam> | ||||
|     /// <param name="dic">字典</param> | ||||
|     /// <param name="newDic">新字典</param> | ||||
|     internal static void AddOrUpdate<T>(this ConcurrentDictionary<string, T> dic, Dictionary<string, T> newDic) | ||||
|     internal static void AddOrUpdate<T>(this NonBlockingDictionary<string, T> dic, Dictionary<string, T> newDic) | ||||
|     { | ||||
|         foreach (var (key, value) in newDic) | ||||
|         { | ||||
|   | ||||
| @@ -94,7 +94,7 @@ public static class AspNetCoreBuilderServiceCollectionExtensions | ||||
|     /// <param name="mvcBuilder"></param> | ||||
|     /// <param name="configure"></param> | ||||
|     /// <returns></returns> | ||||
|     public static IMvcBuilder AddFromConvertBinding(this IMvcBuilder mvcBuilder, Action<ConcurrentDictionary<Type, Type>> configure = default) | ||||
|     public static IMvcBuilder AddFromConvertBinding(this IMvcBuilder mvcBuilder, Action<NonBlockingDictionary<Type, Type>> configure = default) | ||||
|     { | ||||
|         mvcBuilder.Services.AddFromConvertBinding(configure); | ||||
|  | ||||
| @@ -107,13 +107,13 @@ public static class AspNetCoreBuilderServiceCollectionExtensions | ||||
|     /// <param name="services"></param> | ||||
|     /// <param name="configure"></param> | ||||
|     /// <returns></returns> | ||||
|     public static IServiceCollection AddFromConvertBinding(this IServiceCollection services, Action<ConcurrentDictionary<Type, Type>> configure = default) | ||||
|     public static IServiceCollection AddFromConvertBinding(this IServiceCollection services, Action<NonBlockingDictionary<Type, Type>> configure = default) | ||||
|     { | ||||
|         // 非 Web 环境跳过注册 | ||||
|         if (App.WebHostEnvironment == default) return services; | ||||
|  | ||||
|         // 定义模型绑定转换器集合 | ||||
|         var modelBinderConverts = new ConcurrentDictionary<Type, Type>(); | ||||
|         var modelBinderConverts = new NonBlockingDictionary<Type, Type>(); | ||||
|         modelBinderConverts.TryAdd(typeof(DateTime), typeof(DateTimeModelConvertBinder)); | ||||
|         modelBinderConverts.TryAdd(typeof(DateTimeOffset), typeof(DateTimeOffsetModelConvertBinder)); | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.AspNetCore; | ||||
|  | ||||
|   | ||||
| @@ -27,13 +27,13 @@ public class FromConvertBinder : IModelBinder | ||||
|     /// <summary> | ||||
|     /// 定义模型绑定转换器集合 | ||||
|     /// </summary> | ||||
|     private readonly ConcurrentDictionary<Type, Type> _modelBinderConverts; | ||||
|     private readonly NonBlockingDictionary<Type, Type> _modelBinderConverts; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 构造函数 | ||||
|     /// </summary> | ||||
|     /// <param name="modelBinderConverts">定义模型绑定转换器集合</param> | ||||
|     public FromConvertBinder(ConcurrentDictionary<Type, Type> modelBinderConverts) | ||||
|     public FromConvertBinder(NonBlockingDictionary<Type, Type> modelBinderConverts) | ||||
|     { | ||||
|         _modelBinderConverts = modelBinderConverts; | ||||
|     } | ||||
|   | ||||
| @@ -28,13 +28,13 @@ public class FromConvertBinderProvider : IModelBinderProvider | ||||
|     /// <summary> | ||||
|     /// 定义模型绑定转换器集合 | ||||
|     /// </summary> | ||||
|     private readonly ConcurrentDictionary<Type, Type> _modelBinderConverts; | ||||
|     private readonly NonBlockingDictionary<Type, Type> _modelBinderConverts; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 构造函数 | ||||
|     /// </summary> | ||||
|     /// <param name="modelBinderConverts">定义模型绑定转换器集合</param> | ||||
|     public FromConvertBinderProvider(ConcurrentDictionary<Type, Type> modelBinderConverts) | ||||
|     public FromConvertBinderProvider(NonBlockingDictionary<Type, Type> modelBinderConverts) | ||||
|     { | ||||
|         _modelBinderConverts = modelBinderConverts; | ||||
|     } | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.AspNetCore; | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||
| using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.AspNetCore; | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ using System.Reflection; | ||||
|  | ||||
| using ThingsGateway; | ||||
| using ThingsGateway.ConfigurableOptions; | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace Microsoft.Extensions.DependencyInjection; | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ using System.ComponentModel.DataAnnotations; | ||||
| using System.Reflection; | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Templates.Extensions; | ||||
|  | ||||
| namespace ThingsGateway.DataValidation; | ||||
| @@ -40,7 +40,7 @@ public static class DataValidator | ||||
|     /// <summary> | ||||
|     /// 验证类型正则表达式 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<string, ValidationItemMetadataAttribute> ValidationItemMetadatas; | ||||
|     private static readonly NonBlockingDictionary<string, ValidationItemMetadataAttribute> ValidationItemMetadatas; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 构造函数 | ||||
| @@ -57,7 +57,7 @@ public static class DataValidator | ||||
|         ValidationItemMetadatas = GetValidationValidationItemMetadatas(); | ||||
|  | ||||
|         // 缓存所有正则表达式 | ||||
|         GetValidationTypeValidationItemMetadataCached = new ConcurrentDictionary<object, (string, ValidationItemMetadataAttribute)>(); | ||||
|         GetValidationTypeValidationItemMetadataCached = new NonBlockingDictionary<object, (string, ValidationItemMetadataAttribute)>(); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
| @@ -203,7 +203,7 @@ public static class DataValidator | ||||
|     /// <summary> | ||||
|     /// 获取验证类型验证Item集合 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<object, (string, ValidationItemMetadataAttribute)> GetValidationTypeValidationItemMetadataCached; | ||||
|     private static readonly NonBlockingDictionary<object, (string, ValidationItemMetadataAttribute)> GetValidationTypeValidationItemMetadataCached; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取验证类型正则表达式(需要缓存) | ||||
| @@ -267,9 +267,9 @@ public static class DataValidator | ||||
|     /// 获取验证类型所有有效的正则表达式 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     private static ConcurrentDictionary<string, ValidationItemMetadataAttribute> GetValidationValidationItemMetadatas() | ||||
|     private static NonBlockingDictionary<string, ValidationItemMetadataAttribute> GetValidationValidationItemMetadatas() | ||||
|     { | ||||
|         var vaidationItems = new ConcurrentDictionary<string, ValidationItemMetadataAttribute>(); | ||||
|         var vaidationItems = new NonBlockingDictionary<string, ValidationItemMetadataAttribute>(); | ||||
|  | ||||
|         // 查找所有 [ValidationMessageType] 类型中的 [ValidationMessage] 消息定义 | ||||
|         var customErrorMessages = ValidationMessageTypes.SelectMany(u => u.GetFields() | ||||
|   | ||||
| @@ -353,7 +353,7 @@ public static class DependencyInjectionServiceCollectionExtensions | ||||
|     /// <summary> | ||||
|     /// 类型名称集合 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<string, Type> TypeNamedCollection; | ||||
|     private static readonly NonBlockingDictionary<string, Type> TypeNamedCollection; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 创建代理方法 | ||||
| @@ -374,7 +374,7 @@ public static class DependencyInjectionServiceCollectionExtensions | ||||
|         GlobalServiceProxyType = App.EffectiveTypes | ||||
|             .FirstOrDefault(u => typeof(AspectDispatchProxy).IsAssignableFrom(u) && typeof(IGlobalDispatchProxy).IsAssignableFrom(u) && u.IsClass && !u.IsInterface && !u.IsAbstract); | ||||
|  | ||||
|         TypeNamedCollection = new ConcurrentDictionary<string, Type>(); | ||||
|         TypeNamedCollection = new NonBlockingDictionary<string, Type>(); | ||||
|         DispatchCreateMethod = typeof(AspectDispatchProxy).GetMethod(nameof(AspectDispatchProxy.Create)); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ using System.Collections.Concurrent; | ||||
| using System.Reflection; | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.UnifyResult; | ||||
|  | ||||
| namespace ThingsGateway.DynamicApiController; | ||||
|   | ||||
| @@ -28,21 +28,21 @@ internal static class Penetrates | ||||
|     /// <summary> | ||||
|     /// 请求动词映射字典 | ||||
|     /// </summary> | ||||
|     internal static ConcurrentDictionary<string, string> VerbToHttpMethods { get; private set; } | ||||
|     internal static NonBlockingDictionary<string, string> VerbToHttpMethods { get; private set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 控制器排序集合 | ||||
|     /// </summary> | ||||
|     internal static ConcurrentDictionary<string, (string, int, Type)> ControllerOrderCollection { get; set; } | ||||
|     internal static NonBlockingDictionary<string, (string, int, Type)> ControllerOrderCollection { get; set; } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 构造函数 | ||||
|     /// </summary> | ||||
|     static Penetrates() | ||||
|     { | ||||
|         ControllerOrderCollection = new ConcurrentDictionary<string, (string, int, Type)>(); | ||||
|         ControllerOrderCollection = new NonBlockingDictionary<string, (string, int, Type)>(); | ||||
|  | ||||
|         VerbToHttpMethods = new ConcurrentDictionary<string, string> | ||||
|         VerbToHttpMethods = new NonBlockingDictionary<string, string> | ||||
|         { | ||||
|             ["post"] = "POST", | ||||
|             ["add"] = "POST", | ||||
| @@ -67,13 +67,13 @@ internal static class Penetrates | ||||
|             ["patch"] = "PATCH" | ||||
|         }; | ||||
|  | ||||
|         //IsApiControllerCached = new ConcurrentDictionary<Type, bool>(); | ||||
|         //IsApiControllerCached = new NonBlockingDictionary<Type, bool>(); | ||||
|     } | ||||
|  | ||||
|     ///// <summary> | ||||
|     ///// <see cref="IsApiController(Type)"/> 缓存集合 | ||||
|     ///// </summary> | ||||
|     //private static readonly ConcurrentDictionary<Type, bool> IsApiControllerCached; | ||||
|     //private static readonly NonBlockingDictionary<Type, bool> IsApiControllerCached; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 是否是Api控制器 | ||||
|   | ||||
| @@ -61,7 +61,7 @@ internal sealed class EventBusHostedService : BackgroundService | ||||
|     /// <summary> | ||||
|     /// 事件处理程序集合 | ||||
|     /// </summary> | ||||
|     private readonly ConcurrentDictionary<EventHandlerWrapper, EventHandlerWrapper> _eventHandlers = new(); | ||||
|     private readonly NonBlockingDictionary<EventHandlerWrapper, EventHandlerWrapper> _eventHandlers = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 构造函数 | ||||
| @@ -295,7 +295,8 @@ internal sealed class EventBusHostedService : BackgroundService | ||||
|                         , retryAction: (total, times) => | ||||
|                         { | ||||
|                             // 输出重试日志 | ||||
|                             _logger.LogWarning("Retrying {times}/{total} times for {EventId}", times, total, eventSource.EventId); | ||||
|                             if (_logger?.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Warning) == true) | ||||
|                                 _logger.LogWarning("Retrying {times}/{total} times for {EventId}", times, total, eventSource.EventId); | ||||
|                         }).ConfigureAwait(false); | ||||
|                     } | ||||
|                     else | ||||
|   | ||||
| @@ -17,7 +17,7 @@ using System.ComponentModel.DataAnnotations; | ||||
| using System.Diagnostics; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Templates.Extensions; | ||||
|  | ||||
| namespace ThingsGateway.FriendlyException; | ||||
| @@ -31,7 +31,7 @@ public static class Oops | ||||
|     /// <summary> | ||||
|     /// 方法错误异常特性 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<MethodBase, MethodIfException> _errorMethods; | ||||
|     private static readonly NonBlockingDictionary<MethodBase, MethodIfException> _errorMethods; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 错误代码类型 | ||||
| @@ -41,7 +41,7 @@ public static class Oops | ||||
|     /// <summary> | ||||
|     /// 错误消息字典 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<string, string> _errorCodeMessages; | ||||
|     private static readonly NonBlockingDictionary<string, string> _errorCodeMessages; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 友好异常设置 | ||||
| @@ -53,7 +53,7 @@ public static class Oops | ||||
|     /// </summary> | ||||
|     static Oops() | ||||
|     { | ||||
|         _errorMethods = new ConcurrentDictionary<MethodBase, MethodIfException>(); | ||||
|         _errorMethods = new NonBlockingDictionary<MethodBase, MethodIfException>(); | ||||
|         _friendlyExceptionSettings = App.GetConfig<FriendlyExceptionSettingsOptions>("FriendlyExceptionSettings", true); | ||||
|         _errorCodeTypes = GetErrorCodeTypes(); | ||||
|         _errorCodeMessages = GetErrorCodeMessages(); | ||||
| @@ -258,9 +258,9 @@ public static class Oops | ||||
|     /// 获取所有错误消息 | ||||
|     /// </summary> | ||||
|     /// <returns></returns> | ||||
|     private static ConcurrentDictionary<string, string> GetErrorCodeMessages() | ||||
|     private static NonBlockingDictionary<string, string> GetErrorCodeMessages() | ||||
|     { | ||||
|         var defaultErrorCodeMessages = new ConcurrentDictionary<string, string>(); | ||||
|         var defaultErrorCodeMessages = new NonBlockingDictionary<string, string>(); | ||||
|  | ||||
|         // 查找所有 [ErrorCodeType] 类型中的 [ErrorCodeMetadata] 元数据定义 | ||||
|         var errorCodeMessages = _errorCodeTypes.SelectMany(u => u.GetFields().Where(u => u.IsDefined(typeof(ErrorCodeItemMetadataAttribute)))) | ||||
|   | ||||
| @@ -16,7 +16,7 @@ using Microsoft.AspNetCore.SignalR; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway; | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.InstantMessaging; | ||||
|  | ||||
| namespace Microsoft.AspNetCore.Builder; | ||||
|   | ||||
| @@ -23,7 +23,7 @@ public static class ILoggerExtensions | ||||
|     /// 设置日志上下文 | ||||
|     /// </summary> | ||||
|     /// <param name="logger"></param> | ||||
|     /// <param name="properties">建议使用 ConcurrentDictionary 类型</param> | ||||
|     /// <param name="properties">建议使用 NonBlockingDictionary 类型</param> | ||||
|     /// <returns></returns> | ||||
|     public static IDisposable ScopeContext(this ILogger logger, IDictionary<string, object> properties) | ||||
|     { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||
| // ------------------------------------------------------------------------ | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.Logging; | ||||
|  | ||||
|   | ||||
| @@ -82,7 +82,7 @@ public static class StringLoggingExtensions | ||||
|     /// 配置日志上下文 | ||||
|     /// </summary> | ||||
|     /// <param name="message"></param> | ||||
|     /// <param name="properties">建议使用 ConcurrentDictionary 类型</param> | ||||
|     /// <param name="properties">建议使用 NonBlockingDictionary 类型</param> | ||||
|     /// <returns></returns> | ||||
|     public static StringLoggingPart ScopeContext(this string message, IDictionary<string, object> properties) | ||||
|     { | ||||
|   | ||||
| @@ -44,7 +44,7 @@ public sealed class FileLoggerProvider : ILoggerProvider, ISupportExternalScope | ||||
|     /// 记录日志所有滚动文件名 | ||||
|     /// </summary> | ||||
|     /// <remarks>只有 MaxRollingFiles 和 FileSizeLimitBytes 大于 0 有效</remarks> | ||||
|     internal readonly ConcurrentDictionary<string, FileInfo> _rollingFileNames = new(); | ||||
|     internal readonly NonBlockingDictionary<string, FileInfo> _rollingFileNames = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 文件日志写入器 | ||||
|   | ||||
| @@ -36,7 +36,7 @@ using System.Text.Json; | ||||
|  | ||||
| using ThingsGateway; | ||||
| using ThingsGateway.DataValidation; | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.FriendlyException; | ||||
| using ThingsGateway.JsonSerialization; | ||||
| using ThingsGateway.Logging; | ||||
|   | ||||
| @@ -94,7 +94,7 @@ public sealed partial class StringLoggingPart | ||||
|     /// <summary> | ||||
|     /// 配置日志上下文 | ||||
|     /// </summary> | ||||
|     /// <param name="properties">建议使用 ConcurrentDictionary 类型</param> | ||||
|     /// <param name="properties">建议使用 NonBlockingDictionary 类型</param> | ||||
|     /// <returns></returns> | ||||
|     public StringLoggingPart ScopeContext(IDictionary<string, object> properties) | ||||
|     { | ||||
|   | ||||
| @@ -57,7 +57,7 @@ public static class Log | ||||
|     /// <summary> | ||||
|     /// 配置日志上下文 | ||||
|     /// </summary> | ||||
|     /// <param name="properties">建议使用 ConcurrentDictionary 类型</param> | ||||
|     /// <param name="properties">建议使用 NonBlockingDictionary 类型</param> | ||||
|     /// <returns></returns> | ||||
|     public static (ILogger logger, IDisposable scope) ScopeContext(IDictionary<string, object> properties) | ||||
|     { | ||||
|   | ||||
| @@ -16,7 +16,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; | ||||
| using System.Linq.Expressions; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Options; | ||||
|  | ||||
| namespace Microsoft.Extensions.Options; | ||||
|   | ||||
| @@ -21,7 +21,7 @@ internal sealed class JobCancellationToken : IJobCancellationToken | ||||
|     /// <summary> | ||||
|     /// 取消作业执行 Token 集合 | ||||
|     /// </summary> | ||||
|     private readonly ConcurrentDictionary<string, CancellationTokenSource> _cancellationTokenSources; | ||||
|     private readonly NonBlockingDictionary<string, CancellationTokenSource> _cancellationTokenSources; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 作业调度器日志服务 | ||||
|   | ||||
| @@ -167,7 +167,7 @@ public partial class JobDetail | ||||
|     /// <summary> | ||||
|     /// 带命名规则的数据库列名 | ||||
|     /// </summary> | ||||
|     private readonly ConcurrentDictionary<NamingConventions, string[]> _namingColumnNames = new(); | ||||
|     private readonly NonBlockingDictionary<NamingConventions, string[]> _namingColumnNames = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取数据库列名 | ||||
|   | ||||
| @@ -65,7 +65,7 @@ internal sealed partial class SchedulerFactory : ISchedulerFactory | ||||
|     /// <summary> | ||||
|     /// 作业计划集合 | ||||
|     /// </summary> | ||||
|     private readonly ConcurrentDictionary<string, Scheduler> _schedulers = new(); | ||||
|     private readonly NonBlockingDictionary<string, Scheduler> _schedulers = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 作业计划构建器集合 | ||||
|   | ||||
| @@ -369,11 +369,13 @@ internal sealed class ScheduleHostedService : BackgroundService | ||||
|                             // 写入作业执行详细日志 | ||||
|                             if (executionException == null) | ||||
|                             { | ||||
|                                 jobLogger?.LogInformation("{jobExecutingContext}", jobExecutingContext); | ||||
|                                 if (jobLogger?.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Information) == true) | ||||
|                                     jobLogger?.LogInformation("{jobExecutingContext}", jobExecutingContext); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 jobLogger?.LogError(executionException, "{jobExecutingContext}", jobExecutingContext); | ||||
|                                 if (jobLogger?.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Error) == true) | ||||
|                                     jobLogger?.LogError(executionException, "{jobExecutingContext}", jobExecutingContext); | ||||
|                             } | ||||
|  | ||||
|                             // 记录作业触发器运行信息 | ||||
|   | ||||
| @@ -380,7 +380,7 @@ public partial class Trigger | ||||
|     /// <summary> | ||||
|     /// 带命名规则的数据库列名 | ||||
|     /// </summary> | ||||
|     private readonly ConcurrentDictionary<NamingConventions, string[]> _namingColumnNames = new(); | ||||
|     private readonly NonBlockingDictionary<NamingConventions, string[]> _namingColumnNames = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取数据库列名 | ||||
|   | ||||
| @@ -31,7 +31,7 @@ using System.Xml.Linq; | ||||
| using System.Xml.XPath; | ||||
|  | ||||
| using ThingsGateway.DynamicApiController; | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Reflection; | ||||
|  | ||||
| namespace ThingsGateway.SpecificationDocument; | ||||
| @@ -83,11 +83,11 @@ public static class SpecificationDocumentBuilder | ||||
|  | ||||
|         // 初始化常量 | ||||
|         _groupOrderRegex = new Regex(@"@(?<order>[0-9]+$)"); | ||||
|         GetActionGroupsCached = new ConcurrentDictionary<MethodInfo, IEnumerable<GroupExtraInfo>>(); | ||||
|         GetControllerGroupsCached = new ConcurrentDictionary<Type, IEnumerable<GroupExtraInfo>>(); | ||||
|         GetGroupOpenApiInfoCached = new ConcurrentDictionary<string, SpecificationOpenApiInfo>(); | ||||
|         GetControllerTagCached = new ConcurrentDictionary<ControllerActionDescriptor, string>(); | ||||
|         GetActionTagCached = new ConcurrentDictionary<ApiDescription, string>(); | ||||
|         GetActionGroupsCached = new NonBlockingDictionary<MethodInfo, IEnumerable<GroupExtraInfo>>(); | ||||
|         GetControllerGroupsCached = new NonBlockingDictionary<Type, IEnumerable<GroupExtraInfo>>(); | ||||
|         GetGroupOpenApiInfoCached = new NonBlockingDictionary<string, SpecificationOpenApiInfo>(); | ||||
|         GetControllerTagCached = new NonBlockingDictionary<ControllerActionDescriptor, string>(); | ||||
|         GetActionTagCached = new NonBlockingDictionary<ApiDescription, string>(); | ||||
|  | ||||
|         // 默认分组,支持多个逗号分割 | ||||
|         DocumentGroupExtras = new List<GroupExtraInfo> { ResolveGroupExtraInfo(_specificationDocumentSettings.DefaultGroupName) }; | ||||
| @@ -143,7 +143,7 @@ public static class SpecificationDocumentBuilder | ||||
|     /// <summary> | ||||
|     /// 获取分组信息缓存集合 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<string, SpecificationOpenApiInfo> GetGroupOpenApiInfoCached; | ||||
|     private static readonly NonBlockingDictionary<string, SpecificationOpenApiInfo> GetGroupOpenApiInfoCached; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取分组配置信息 | ||||
| @@ -738,7 +738,7 @@ public static class SpecificationDocumentBuilder | ||||
|     /// <summary> | ||||
|     /// 获取控制器组缓存集合 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<Type, IEnumerable<GroupExtraInfo>> GetControllerGroupsCached; | ||||
|     private static readonly NonBlockingDictionary<Type, IEnumerable<GroupExtraInfo>> GetControllerGroupsCached; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取控制器分组列表 | ||||
| @@ -773,7 +773,7 @@ public static class SpecificationDocumentBuilder | ||||
|     /// <summary> | ||||
|     /// <see cref="GetActionGroups(MethodInfo)"/> 缓存集合 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<MethodInfo, IEnumerable<GroupExtraInfo>> GetActionGroupsCached; | ||||
|     private static readonly NonBlockingDictionary<MethodInfo, IEnumerable<GroupExtraInfo>> GetActionGroupsCached; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取动作方法分组列表 | ||||
| @@ -808,7 +808,7 @@ public static class SpecificationDocumentBuilder | ||||
|     /// <summary> | ||||
|     /// <see cref="GetActionTag(ApiDescription)"/> 缓存集合 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<ControllerActionDescriptor, string> GetControllerTagCached; | ||||
|     private static readonly NonBlockingDictionary<ControllerActionDescriptor, string> GetControllerTagCached; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取控制器标签 | ||||
| @@ -835,7 +835,7 @@ public static class SpecificationDocumentBuilder | ||||
|     /// <summary> | ||||
|     /// <see cref="GetActionTag(ApiDescription)"/> 缓存集合 | ||||
|     /// </summary> | ||||
|     private static readonly ConcurrentDictionary<ApiDescription, string> GetActionTagCached; | ||||
|     private static readonly NonBlockingDictionary<ApiDescription, string> GetActionTagCached; | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取动作方法标签 | ||||
|   | ||||
| @@ -20,7 +20,7 @@ using System.Reflection; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.SpecificationDocument; | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.Templates.Extensions; | ||||
|  | ||||
|   | ||||
| @@ -29,7 +29,7 @@ | ||||
| 	</ItemGroup> | ||||
|  | ||||
| 	<ItemGroup> | ||||
| 		<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.5" /> | ||||
| 		<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.6" /> | ||||
| 		<PackageReference Include="System.Text.Encoding.CodePages" Version="$(NET10Version)" /> | ||||
| 	</ItemGroup> | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ using Microsoft.AspNetCore.Http; | ||||
|  | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.UnifyResult; | ||||
|  | ||||
| namespace Microsoft.AspNetCore.Mvc; | ||||
|   | ||||
| @@ -22,7 +22,7 @@ using Microsoft.Extensions.Options; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.FriendlyException; | ||||
|  | ||||
| namespace ThingsGateway.UnifyResult; | ||||
| @@ -51,12 +51,12 @@ public static class UnifyContext | ||||
|     /// <summary> | ||||
|     /// 规范化结果提供器 | ||||
|     /// </summary> | ||||
|     internal static ConcurrentDictionary<string, UnifyMetadata> UnifyProviders = new(); | ||||
|     internal static NonBlockingDictionary<string, UnifyMetadata> UnifyProviders = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 规范化序列化配置 | ||||
|     /// </summary> | ||||
|     internal static ConcurrentDictionary<string, object> UnifySerializerSettings = new(); | ||||
|     internal static NonBlockingDictionary<string, object> UnifySerializerSettings = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// 获取异常元数据 | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.Converters.Json; | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Reflection; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="Assembly" /> 拓展类 | ||||
|   | ||||
| @@ -11,10 +11,10 @@ | ||||
|  | ||||
| using System.Collections.Concurrent; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="ConcurrentDictionary{TKey, TValue}" /> 拓展类 | ||||
| ///     <see cref="NonBlockingDictionary{TKey, TValue}" /> 拓展类 | ||||
| /// </summary> | ||||
| internal static class ConcurrentDictionaryExtensions | ||||
| { | ||||
| @@ -24,7 +24,7 @@ internal static class ConcurrentDictionaryExtensions | ||||
|     /// <typeparam name="TKey">字典键类型</typeparam> | ||||
|     /// <typeparam name="TValue">字典值类型</typeparam> | ||||
|     /// <param name="dictionary"> | ||||
|     ///     <see cref="ConcurrentDictionary{TKey, TValue}" /> | ||||
|     ///     <see cref="NonBlockingDictionary{TKey, TValue}" /> | ||||
|     /// </param> | ||||
|     /// <param name="key"> | ||||
|     ///     <typeparamref name="TKey" /> | ||||
| @@ -36,7 +36,7 @@ internal static class ConcurrentDictionaryExtensions | ||||
|     /// <returns> | ||||
|     ///     <see cref="bool" /> | ||||
|     /// </returns> | ||||
|     internal static bool TryUpdate<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary | ||||
|     internal static bool TryUpdate<TKey, TValue>(this NonBlockingDictionary<TKey, TValue> dictionary | ||||
|         , TKey key | ||||
|         , Func<TValue, TValue> updateFactory | ||||
|         , out TValue? value) | ||||
|   | ||||
| @@ -15,7 +15,7 @@ using Microsoft.Extensions.Hosting; | ||||
|  | ||||
| using System.Reflection; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     核心模块 <see cref="IServiceCollection" /> 拓展类 | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Data; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="DataTable" /> 和 <see cref="DataSet" /> 拓展类 | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||
| // ------------------------------------------------------------------------ | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     委托拓展类 | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using System.ComponentModel; | ||||
| using System.Reflection; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     枚举拓展类 | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||
| // ------------------------------------------------------------------------ | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="EventHandler{TEventArgs}" /> 拓展类 | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="ICollection{T}" /> 拓展类 | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Collections.Concurrent; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="IDictionary{TKey, TValue}" /> 拓展类 | ||||
| @@ -241,7 +241,7 @@ internal static class IDictionaryExtensions | ||||
|     /// </summary> | ||||
|     /// <remarks>其中键是由值通过给定的选择器函数生成的。</remarks> | ||||
|     /// <param name="dictionary"> | ||||
|     ///     <see cref="ConcurrentDictionary{TKey, TValue}" /> | ||||
|     ///     <see cref="NonBlockingDictionary{TKey, TValue}" /> | ||||
|     /// </param> | ||||
|     /// <param name="values"> | ||||
|     ///     <see cref="IEnumerable{T}" /> | ||||
| @@ -249,7 +249,7 @@ internal static class IDictionaryExtensions | ||||
|     /// <param name="keySelector">键选择器</param> | ||||
|     /// <typeparam name="TKey">字典键类型</typeparam> | ||||
|     /// <typeparam name="TValue">字典值类型</typeparam> | ||||
|     internal static void TryAdd<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dictionary, | ||||
|     internal static void TryAdd<TKey, TValue>(this NonBlockingDictionary<TKey, TValue> dictionary, | ||||
|         IEnumerable<TValue>? values, Func<TValue, TKey> keySelector) | ||||
|         where TKey : notnull | ||||
|     { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||
| // ------------------------------------------------------------------------ | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="IEnumerable" /> 拓展类 | ||||
|   | ||||
| @@ -18,7 +18,7 @@ using System.Text.RegularExpressions; | ||||
| using System.Xml; | ||||
| using System.Xml.Linq; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     System.Text.Json 拓展类 | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using System.Linq.Expressions; | ||||
| using System.Reflection; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="Expression" /> 拓展类 | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.Reflection; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="MethodInfo" /> 拓展类 | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||
| // ------------------------------------------------------------------------ | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     数值类型拓展类 | ||||
|   | ||||
| @@ -17,7 +17,7 @@ using System.Reflection; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="string" /> 拓展类 | ||||
|   | ||||
| @@ -15,7 +15,7 @@ using System.Reflection; | ||||
| using System.Reflection.Emit; | ||||
| using System.Runtime.CompilerServices; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="Type" /> 拓展类 | ||||
|   | ||||
| @@ -13,7 +13,7 @@ using System.Buffers; | ||||
| using System.Text; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="Utf8JsonReader" /> 拓展类 | ||||
|   | ||||
| @@ -16,7 +16,7 @@ using System.Text.Json; | ||||
|  | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.Extensions; | ||||
| namespace ThingsGateway.Extension; | ||||
|  | ||||
| /// <summary> | ||||
| ///     <see cref="object" /> 拓展类 | ||||
|   | ||||
| @@ -21,20 +21,20 @@ internal sealed class CoreOptions | ||||
|     /// <summary> | ||||
|     ///     已注册的组件元数据集合 | ||||
|     /// </summary> | ||||
|     internal readonly ConcurrentDictionary<string, ComponentMetadata> _metadataOfRegistered; | ||||
|     internal readonly NonBlockingDictionary<string, ComponentMetadata> _metadataOfRegistered; | ||||
|  | ||||
|     /// <summary> | ||||
|     ///     子选项集合 | ||||
|     /// </summary> | ||||
|     internal readonly ConcurrentDictionary<Type, object> _optionsInstances; | ||||
|     internal readonly NonBlockingDictionary<Type, object> _optionsInstances; | ||||
|  | ||||
|     /// <summary> | ||||
|     ///     <inheritdoc cref="CoreOptions" /> | ||||
|     /// </summary> | ||||
|     internal CoreOptions() | ||||
|     { | ||||
|         _optionsInstances = new ConcurrentDictionary<Type, object>(); | ||||
|         _metadataOfRegistered = new ConcurrentDictionary<string, ComponentMetadata>(StringComparer.OrdinalIgnoreCase); | ||||
|         _optionsInstances = new NonBlockingDictionary<Type, object>(); | ||||
|         _metadataOfRegistered = new NonBlockingDictionary<string, ComponentMetadata>(StringComparer.OrdinalIgnoreCase); | ||||
|  | ||||
|         EntryComponentTypes = []; | ||||
|     } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ using System.Collections.Concurrent; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.Reflection; | ||||
|  | ||||
| @@ -32,7 +32,7 @@ public sealed class ObjectPropertyGetter<T> where T : class | ||||
|     /// <summary> | ||||
|     ///     对象类型实例属性值访问器集合 | ||||
|     /// </summary> | ||||
|     internal readonly ConcurrentDictionary<string, Func<object, object?>> _propertyGetters = new(); | ||||
|     internal readonly NonBlockingDictionary<string, Func<object, object?>> _propertyGetters = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     ///     <inheritdoc cref="ObjectPropertyGetter{T}" /> | ||||
|   | ||||
| @@ -13,7 +13,7 @@ using System.Collections.Concurrent; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.Reflection; | ||||
|  | ||||
| @@ -32,7 +32,7 @@ public sealed class ObjectPropertySetter<T> where T : class | ||||
|     /// <summary> | ||||
|     ///     对象类型实例属性值设置器集合 | ||||
|     /// </summary> | ||||
|     internal readonly ConcurrentDictionary<string, Action<object, object?>> _propertySetters = new(); | ||||
|     internal readonly NonBlockingDictionary<string, Action<object, object?>> _propertySetters = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     ///     <inheritdoc cref="ObjectPropertySetter{T}" /> | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.Utilities; | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.Utilities; | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ using Microsoft.Net.Http.Headers; | ||||
| using System.Net.Mime; | ||||
|  | ||||
| using ThingsGateway.AspNetCore.Extensions; | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue; | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using System.Net.Http.Headers; | ||||
| using System.Threading.Channels; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ using System.Text; | ||||
| using System.Text.Json; | ||||
| using System.Threading.Channels; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ using Microsoft.Extensions.Logging; | ||||
| using System.Reflection; | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ using System.Net.Mime; | ||||
| using System.Text; | ||||
| using System.Text.Json; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue; | ||||
|   | ||||
| @@ -16,7 +16,7 @@ using System.Globalization; | ||||
| using System.Net.Http.Headers; | ||||
| using System.Net.Mime; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| using CacheControlHeaderValue = System.Net.Http.Headers.CacheControlHeaderValue; | ||||
| using StringWithQualityHeaderValue = System.Net.Http.Headers.StringWithQualityHeaderValue; | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
| using System.Collections.Concurrent; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
| @@ -27,7 +27,7 @@ public sealed class HttpDeclarativeBuilder | ||||
|     /// <summary> | ||||
|     ///     HTTP 声明式 <see cref="IHttpDeclarativeExtractor" /> 提取器集合 | ||||
|     /// </summary> | ||||
|     internal static readonly ConcurrentDictionary<Type, IHttpDeclarativeExtractor> _extractors = new([ | ||||
|     internal static readonly NonBlockingDictionary<Type, IHttpDeclarativeExtractor> _extractors = new([ | ||||
|         new(typeof(BaseAddressDeclarativeExtractor), new BaseAddressDeclarativeExtractor()), | ||||
|         new(typeof(ValidationDeclarativeExtractor), new ValidationDeclarativeExtractor()), | ||||
|         new(typeof(AutoSetHostHeaderDeclarativeExtractor), new AutoSetHostHeaderDeclarativeExtractor()), | ||||
| @@ -56,7 +56,7 @@ public sealed class HttpDeclarativeBuilder | ||||
|     ///     HTTP 声明式 <see cref="IHttpDeclarativeExtractor" /> 提取器集合(冻结) | ||||
|     /// </summary> | ||||
|     /// <remarks>该集合用于确保某些 HTTP 声明式提取器始终位于最后。</remarks> | ||||
|     internal static readonly ConcurrentDictionary<Type, IFrozenHttpDeclarativeExtractor> _frozenExtractors = new([ | ||||
|     internal static readonly NonBlockingDictionary<Type, IFrozenHttpDeclarativeExtractor> _frozenExtractors = new([ | ||||
|         new(typeof(MultipartDeclarativeExtractor), new MultipartDeclarativeExtractor()), | ||||
|         new(typeof(HttpMultipartFormDataBuilderDeclarativeExtractor), | ||||
|             new HttpMultipartFormDataBuilderDeclarativeExtractor()), | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using System.Net.Mime; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -14,7 +14,7 @@ using System.Net.Mime; | ||||
| using System.Reflection; | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||
| // ------------------------------------------------------------------------ | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.Reflection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -251,7 +251,8 @@ public sealed class ProfilerDelegatingHandler(ILogger<Logging> logger, IOptions< | ||||
|         // 检查是否配置(注册)了日志程序 | ||||
|         if (remoteOptions.IsLoggingRegistered) | ||||
|         { | ||||
|             logger.Log(remoteOptions.ProfilerLogLevel, "{message}", message); | ||||
|             if (logger?.IsEnabled(remoteOptions.ProfilerLogLevel) == true) | ||||
|                 logger.Log(remoteOptions.ProfilerLogLevel, "{message}", message); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|   | ||||
| @@ -14,7 +14,7 @@ using Microsoft.Extensions.DependencyInjection; | ||||
|  | ||||
| using System.Net.Http.Headers; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote.Extensions; | ||||
|  | ||||
|   | ||||
| @@ -18,7 +18,7 @@ using System.Net.Http.Headers; | ||||
| using System.Text; | ||||
| using System.Text.RegularExpressions; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| using StringWithQualityHeaderValue = System.Net.Http.Headers.StringWithQualityHeaderValue; | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.AspNetCore.Mvc.Controllers; | ||||
| using Microsoft.AspNetCore.Mvc.Filters; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.HttpRemote.Extensions; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
|  | ||||
| using System.Globalization; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ using Microsoft.Extensions.Options; | ||||
| using System.Diagnostics; | ||||
| using System.Threading.Channels; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -15,7 +15,7 @@ using Microsoft.Extensions.Options; | ||||
| using System.Diagnostics; | ||||
| using System.Threading.Channels; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ using Microsoft.Extensions.Options; | ||||
|  | ||||
| using System.Threading.Channels; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -16,7 +16,7 @@ using System.Diagnostics.CodeAnalysis; | ||||
| using System.Text; | ||||
| using System.Threading.Channels; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||
| // ------------------------------------------------------------------------ | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
| using ThingsGateway.Utilities; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|   | ||||
| @@ -14,7 +14,7 @@ using System.Net.Http.Headers; | ||||
| using System.Net.Mime; | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ using System.Net.Http.Headers; | ||||
| using System.Reflection; | ||||
| using System.Text; | ||||
|  | ||||
| using ThingsGateway.Extensions; | ||||
| using ThingsGateway.Extension; | ||||
|  | ||||
| namespace ThingsGateway.HttpRemote; | ||||
|  | ||||
| @@ -27,7 +27,7 @@ public class MessagePackContentProcessor : HttpContentProcessorBase | ||||
|     /// <summary> | ||||
|     ///     MessagePack 序列化器委托字典缓存 | ||||
|     /// </summary> | ||||
|     internal static readonly ConcurrentDictionary<Type, Func<object, byte[]>> _serializerCache = new(); | ||||
|     internal static readonly NonBlockingDictionary<Type, Func<object, byte[]>> _serializerCache = new(); | ||||
|  | ||||
|     /// <summary> | ||||
|     ///     初始化 MessagePack 序列化器委托 | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user