mirror of
https://github.com/RRQM/TouchSocket.git
synced 2025-12-20 10:26:43 +08:00
发布:3.0.14
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>3.0.13</Version>
|
||||
<Version>3.0.14</Version>
|
||||
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
@@ -20,7 +20,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="dotnetCampus.LatestCSharpFeatures" Version="12.0.0" PrivateAssets="all" />
|
||||
<PackageReference Include="dotnetCampus.LatestCSharpFeatures" Version="12.0.1" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(MSBuildProjectName.StartsWith(`TouchSocketPro`))'">
|
||||
@@ -83,13 +83,13 @@
|
||||
<Copy SourceFiles="$(PackageOutputPath)\$(PackageId).$(PackageVersion).nupkg" DestinationFolder="D:\Nuget\local" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup Condition="'$(IsSourceGenerator)'!='True'">
|
||||
<PackageReference Include="Backport.System.Threading.Lock" Version="3.0.3">
|
||||
<!--<ItemGroup Condition="'$(IsSourceGenerator)'!='True'">
|
||||
<PackageReference Include="Backport.System.Threading.Lock" Version="3.1.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<Using Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net9.0'))" Alias="Lock" Include="System.Threading.Lock" />
|
||||
<Using Condition="!$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net9.0'))" Alias="Lock" Include="Backport.System.Threading.Lock" />
|
||||
<Using Alias="LockFactory" Include="Backport.System.Threading.LockFactory" />
|
||||
</ItemGroup>
|
||||
</ItemGroup>-->
|
||||
</Project>
|
||||
@@ -58,7 +58,7 @@ public class WebSocketDmtpSessionClient : ResolverConfigObject, IWebSocketDmtpSe
|
||||
private WebSocketDmtpService m_service;
|
||||
private HttpContext m_httpContext;
|
||||
private string m_id;
|
||||
private readonly Lock m_locker = LockFactory.Create();
|
||||
private readonly Lock m_locker = new Lock();
|
||||
|
||||
#endregion 字段
|
||||
|
||||
|
||||
@@ -36,4 +36,4 @@ internal class InternalScopedResolver : DisposableObject, IScopedResolver
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,4 +131,4 @@ internal class ScopedResolver : IResolver, IKeyedServiceProvider
|
||||
}
|
||||
|
||||
#endregion Resolve
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
////------------------------------------------------------------------------------
|
||||
//// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
//// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
//// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
//// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
//// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
//// Github源代码仓库:https://github.com/RRQM
|
||||
//// API首页:https://touchsocket.net/
|
||||
//// 交流QQ群:234762506
|
||||
//// 感谢您的下载和使用
|
||||
////------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:https://touchsocket.net/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//#if NET45_OR_GREATER || NETSTANDARD2_0
|
||||
//using System;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace TouchSocket.Core;
|
||||
/// <typeparam name="T">队列中元素的类型。</typeparam>
|
||||
public sealed class AsyncBoundedQueue<T> : ValueTaskSource<T>
|
||||
{
|
||||
private readonly Lock m_locker = LockFactory.Create();
|
||||
private readonly Lock m_locker = new Lock();
|
||||
|
||||
// 使用并发队列来存储元素,支持线程安全的操作。
|
||||
private readonly ConcurrentQueue<T> m_queue = new ConcurrentQueue<T>();
|
||||
|
||||
@@ -98,7 +98,7 @@ public class IntelligentDataQueue<T> : ConcurrentQueue<T> where T : IQueueData
|
||||
{
|
||||
private long m_actualSize;
|
||||
private long m_maxSize;
|
||||
private readonly Lock m_lock = LockFactory.Create();
|
||||
private readonly Lock m_lock = new Lock();
|
||||
/// <summary>
|
||||
/// 智能数据安全队列
|
||||
/// </summary>
|
||||
|
||||
@@ -21,4 +21,4 @@ public interface IScopedResolver : IDisposableObject
|
||||
/// 获取解析器实例。
|
||||
/// </summary>
|
||||
IResolver Resolver { get; }
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,4 @@ internal class InternalScopedResolver : DisposableObject, IScopedResolver
|
||||
{
|
||||
this.Resolver = resolver;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace TouchSocket.Core;
|
||||
/// <summary>
|
||||
/// 区间数据包处理适配器,支持以任意字符、字节数组起始与结尾的数据包。
|
||||
/// </summary>
|
||||
public abstract class CustomBetweenAndDataHandlingAdapter<TBetweenAndRequestInfo> : CustomDataHandlingAdapter<TBetweenAndRequestInfo> where TBetweenAndRequestInfo : IBetweenAndRequestInfo
|
||||
public abstract class CustomBetweenAndDataHandlingAdapter<TBetweenAndRequestInfo> : CustomDataHandlingAdapter<TBetweenAndRequestInfo> where TBetweenAndRequestInfo : IRequestInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 起始字符,不可以为null,可以为0长度
|
||||
@@ -47,108 +47,50 @@ public abstract class CustomBetweenAndDataHandlingAdapter<TBetweenAndRequestInfo
|
||||
/// <returns></returns>
|
||||
protected override FilterResult Filter<T>(ref T byteBlock, bool beCached, ref TBetweenAndRequestInfo request, ref int tempCapacity)
|
||||
{
|
||||
if (beCached)
|
||||
ReadOnlySpan<byte> startCode = this.StartCode ?? ReadOnlySpan<byte>.Empty;
|
||||
ReadOnlySpan<byte> endCode = this.EndCode ?? ReadOnlySpan<byte>.Empty;
|
||||
// 检查终止字符是否为空
|
||||
if (endCode.IsEmpty)
|
||||
{
|
||||
var len = 0;
|
||||
var pos = byteBlock.Position;
|
||||
while (true)
|
||||
{
|
||||
var indexEnd = byteBlock.Span.Slice(byteBlock.Position, byteBlock.CanReadLength).IndexOf(this.EndCode);
|
||||
if (indexEnd == -1)
|
||||
{
|
||||
byteBlock.Position = pos;
|
||||
return FilterResult.Cache;
|
||||
}
|
||||
else
|
||||
{
|
||||
len += indexEnd;
|
||||
byteBlock.Position += indexEnd;
|
||||
if (len >= this.MinSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len += this.EndCode.Length;
|
||||
byteBlock.Position += this.EndCode.Length;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//byteBlock.Position = pos;
|
||||
request.OnParsingBody(byteBlock.Span.Slice(pos, len));
|
||||
byteBlock.Position = len + pos;
|
||||
|
||||
if (request.OnParsingEndCode(byteBlock.Span.Slice(byteBlock.Position, this.EndCode.Length)))
|
||||
{
|
||||
byteBlock.Position += this.EndCode.Length;
|
||||
return FilterResult.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
byteBlock.Position += this.EndCode.Length;
|
||||
return FilterResult.GoOn;
|
||||
}
|
||||
ThrowHelper.ThrowException("区间字符适配器的终止字符不能为空");
|
||||
}
|
||||
else
|
||||
// 获取可读取的字节范围
|
||||
var canReadSpan = byteBlock.Span.Slice(byteBlock.Position, byteBlock.CanReadLength);
|
||||
// 查找起始码的索引
|
||||
var startCodeIndex = canReadSpan.IndexOf(startCode);
|
||||
if (startCodeIndex < 0)
|
||||
{
|
||||
var indexStart = byteBlock.Span.Slice(byteBlock.Position, byteBlock.CanReadLength).IndexOf(this.StartCode);
|
||||
if (indexStart == -1)
|
||||
// 未找到起始码,缓存所有数据
|
||||
return FilterResult.Cache;
|
||||
}
|
||||
// 从起始码之后的位置开始查找
|
||||
var searchSpan = canReadSpan.Slice(startCodeIndex + startCode.Length);
|
||||
var currentSearchOffset = 0;
|
||||
while (true)
|
||||
{
|
||||
// 查找终止码的索引
|
||||
var endCodeIndex = searchSpan.IndexOf(endCode);
|
||||
if (endCodeIndex < 0)
|
||||
{
|
||||
// 未找到终止码,缓存所有数据
|
||||
return FilterResult.Cache;
|
||||
}
|
||||
|
||||
var requestInfo = this.GetInstance();
|
||||
|
||||
if (requestInfo.OnParsingStartCode(byteBlock.Span.Slice(byteBlock.Position, this.StartCode.Length)))
|
||||
// 计算区间长度
|
||||
var bodyLength = endCodeIndex + currentSearchOffset;
|
||||
if (bodyLength >= this.MinSize)
|
||||
{
|
||||
byteBlock.Position += this.StartCode.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
byteBlock.Position += 1;
|
||||
return FilterResult.GoOn;
|
||||
}
|
||||
|
||||
request = requestInfo;
|
||||
|
||||
var len = 0;
|
||||
var pos = byteBlock.Position;
|
||||
while (true)
|
||||
{
|
||||
var indexEnd = byteBlock.Span.Slice(byteBlock.Position, byteBlock.CanReadLength).IndexOf(this.EndCode);
|
||||
if (indexEnd == -1)
|
||||
{
|
||||
byteBlock.Position = pos;
|
||||
return FilterResult.Cache;
|
||||
}
|
||||
else
|
||||
{
|
||||
len += indexEnd;
|
||||
byteBlock.Position += indexEnd;
|
||||
|
||||
if (len >= this.MinSize)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
len += this.EndCode.Length;
|
||||
byteBlock.Position += this.EndCode.Length;
|
||||
}
|
||||
}
|
||||
|
||||
//byteBlock.Position = pos;
|
||||
request.OnParsingBody(byteBlock.Span.Slice(pos, len));
|
||||
byteBlock.Position = len + pos;
|
||||
|
||||
if (request.OnParsingEndCode(byteBlock.Span.Slice(byteBlock.Position, this.EndCode.Length)))
|
||||
{
|
||||
byteBlock.Position += this.EndCode.Length;
|
||||
// 区间长度满足要求,提取数据
|
||||
var body = canReadSpan.Slice(startCodeIndex + startCode.Length, bodyLength);
|
||||
request = this.GetInstance(body);
|
||||
// 更新字节块的位置
|
||||
byteBlock.Position += startCodeIndex + startCode.Length + bodyLength + endCode.Length;
|
||||
return FilterResult.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
byteBlock.Position += 1;
|
||||
return FilterResult.GoOn;
|
||||
// 区间长度不满足要求,继续从当前终止码之后查找
|
||||
currentSearchOffset += endCodeIndex + endCode.Length;
|
||||
searchSpan = searchSpan.Slice(endCodeIndex + endCode.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,13 +98,15 @@ public abstract class CustomBetweenAndDataHandlingAdapter<TBetweenAndRequestInfo
|
||||
/// <summary>
|
||||
/// 获取泛型实例。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected abstract TBetweenAndRequestInfo GetInstance();
|
||||
/// <param name="body">数据体</param>
|
||||
/// <returns>泛型实例</returns>
|
||||
protected abstract TBetweenAndRequestInfo GetInstance(ReadOnlySpan<byte> body);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 区间类型的适配器数据模型接口。
|
||||
/// </summary>
|
||||
[Obsolete("此接口已被弃用,请使用IRequestInfo代替约束。具体数据会在CustomBetweenAndDataHandlingAdapter.GetInstance(ReadOnlySpan<byte> body)直接投递。",true)]
|
||||
public interface IBetweenAndRequestInfo : IRequestInfo
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:https://touchsocket.net/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace TouchSocket.Core;
|
||||
@@ -104,4 +116,4 @@ public interface ICountSpliterRequestInfo : IRequestInfo
|
||||
/// <param name="startCode">开始代码。</param>
|
||||
/// <returns>是否成功解析。</returns>
|
||||
bool OnParsing(ReadOnlySpan<byte> startCode);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,16 @@
|
||||
using System;
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:https://touchsocket.net/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace TouchSocket.Core;
|
||||
|
||||
@@ -68,4 +68,4 @@ public ref struct CustomIntEnumerator
|
||||
return this.m_current <= this.m_end;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -879,4 +879,19 @@ public static class SystemExtension
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region IEnumerable
|
||||
/// <summary>
|
||||
/// 获取安全的枚举器。
|
||||
/// </summary>
|
||||
public static IEnumerable<T> GetSafeEnumerator<T>(this IEnumerable<T> enumerator)
|
||||
{
|
||||
if (enumerator is null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return enumerator;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -26,7 +26,7 @@ namespace TouchSocket.Core;
|
||||
|
||||
public static partial class FilePool
|
||||
{
|
||||
private static readonly Lock s_locker = LockFactory.Create();
|
||||
private static readonly Lock s_locker = new Lock();
|
||||
|
||||
private static readonly ConcurrentDictionary<string, FileStorage> m_pathStorage = new ConcurrentDictionary<string, FileStorage>();
|
||||
|
||||
|
||||
@@ -28,12 +28,6 @@ public interface ILog
|
||||
/// <summary>
|
||||
/// 获取或设置日期时间格式
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 这个属性用于定义如何格式化或解析字符串中的日期和时间
|
||||
/// 默认格式为 "yyyy-MM-dd HH:mm:ss ffff",其中 "yyyy" 代表年份,
|
||||
/// "MM" 代表月份,"dd" 代表日期,"HH" 代表小时,
|
||||
/// "mm" 代表分钟,"ss" 代表秒,"ffff" 代表毫秒
|
||||
/// </remarks>
|
||||
string DateTimeFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -43,7 +43,7 @@ public abstract class LoggerBase : ILog
|
||||
protected abstract void WriteLog(LogLevel logLevel, object source, string message, Exception exception);
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置日期时间格式
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 这个属性用于定义如何格式化或解析字符串中的日期和时间
|
||||
|
||||
@@ -14,6 +14,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TouchSocket.Core;
|
||||
@@ -23,7 +24,7 @@ namespace TouchSocket.Core;
|
||||
/// </summary>
|
||||
public sealed class PluginManager : DisposableObject, IPluginManager
|
||||
{
|
||||
private readonly Lock m_locker = LockFactory.Create();
|
||||
private readonly Lock m_locker = new Lock();
|
||||
private readonly IScopedResolver m_scopedResolver;
|
||||
private Dictionary<Type, PluginInvokeLine> m_pluginMethods = new Dictionary<Type, PluginInvokeLine>();
|
||||
|
||||
|
||||
@@ -21,4 +21,4 @@ namespace TouchSocket.Core;
|
||||
public sealed class DynamicMethodAttribute : Attribute
|
||||
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -31,4 +31,4 @@ public enum TaskReturnType
|
||||
/// 返回Task的值
|
||||
/// </summary>
|
||||
TaskObject
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:https://touchsocket.net/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace TouchSocket.Resources {
|
||||
@@ -321,4 +323,4 @@ namespace TouchSocket.Resources {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,4 +24,4 @@ public interface IResult<T> : IResult
|
||||
/// </summary>
|
||||
/// <value>结果值,类型为 T。</value>
|
||||
T Value { get; }
|
||||
}
|
||||
}
|
||||
@@ -80,4 +80,4 @@ public class ResultBase : IResult
|
||||
{
|
||||
return TouchSocketCoreResource.ResultToString.Format(this.ResultCode, this.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,4 +50,4 @@ public static class ResultExtensions
|
||||
{
|
||||
return new Result(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,4 +60,4 @@ public class JsonMemoryToClassSerializerFormatter<TState> : ISerializerFormatter
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ public class AsyncResetEvent : DisposableObject
|
||||
{
|
||||
private readonly bool m_autoReset;
|
||||
|
||||
private readonly Lock m_locker = LockFactory.Create();
|
||||
private readonly Lock m_locker = new Lock();
|
||||
|
||||
private readonly Queue<TaskCompletionSource<bool>> m_waitQueue = new Queue<TaskCompletionSource<bool>>();
|
||||
|
||||
|
||||
17
src/TouchSocket.Core/Threading/Lock.cs
Normal file
17
src/TouchSocket.Core/Threading/Lock.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TouchSocket.Core;
|
||||
|
||||
#if !NET9_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// lock
|
||||
/// </summary>
|
||||
public sealed class Lock
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -72,12 +72,4 @@
|
||||
<CustomToolNamespace>TouchSocket.Resources</CustomToolNamespace>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Backport.System.Threading.Lock" Version="3.1.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Update="dotnetCampus.LatestCSharpFeatures" Version="12.0.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:https://touchsocket.net/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -22,4 +34,4 @@ public interface IWaitDataAsync<T> : IWaitDataBase<T>
|
||||
/// <param name="millisecond">等待的毫秒数。</param>
|
||||
/// <returns>等待数据的状态。</returns>
|
||||
Task<WaitDataStatus> WaitAsync(int millisecond);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:https://touchsocket.net/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System.Threading;
|
||||
|
||||
namespace TouchSocket.Core;
|
||||
@@ -53,4 +65,4 @@ public interface IWaitDataBase<T> : IDisposableObject
|
||||
/// </summary>
|
||||
/// <param name="result">等待结果。</param>
|
||||
void SetResult(T result);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,15 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:https://touchsocket.net/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace TouchSocket.Core;
|
||||
|
||||
/// <summary>
|
||||
@@ -114,4 +126,4 @@ public interface IWaitHandlePool<TWaitData, TWaitDataAsync, T> : IDisposableObje
|
||||
public interface IWaitHandlePool<T> : IWaitHandlePool<WaitData<T>, WaitDataAsync<T>, T> where T : IWaitHandle
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ public abstract class DmtpActor : DependencyObject, IDmtpActor
|
||||
private readonly ConcurrentDictionary<int, InternalChannel> m_userChannels = new ConcurrentDictionary<int, InternalChannel>();
|
||||
private readonly AsyncResetEvent m_handshakeFinished = new AsyncResetEvent(false, false);
|
||||
private CancellationTokenSource m_cancellationTokenSource;
|
||||
private readonly Lock m_syncRoot = LockFactory.Create();
|
||||
private readonly Lock m_syncRoot = new Lock();
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -195,7 +195,7 @@ public abstract class DmtpActor : DependencyObject, IDmtpActor
|
||||
{
|
||||
this.m_handshakeFinished.Set();
|
||||
//verifyResult.Handle = true;
|
||||
throw new TokenVerifyException(verifyResult.Message);
|
||||
throw new TokenVerifyException(verifyResult.Metadata, verifyResult.Message);
|
||||
}
|
||||
}
|
||||
case WaitDataStatus.Overtime:
|
||||
@@ -427,6 +427,8 @@ public abstract class DmtpActor : DependencyObject, IDmtpActor
|
||||
{
|
||||
waitVerify.Id = this.Id;
|
||||
waitVerify.Status = 1;
|
||||
waitVerify.Metadata = args.Metadata;
|
||||
waitVerify.Message = args.Message ?? TouchSocketCoreResource.OperationSuccessful;
|
||||
await this.SendJsonObjectAsync(P2_Handshake_Response, waitVerify).ConfigureAwait(EasyTask.ContinueOnCapturedContext);
|
||||
this.Online = true;
|
||||
args.Message ??= TouchSocketCoreResource.OperationSuccessful;
|
||||
@@ -436,7 +438,8 @@ public abstract class DmtpActor : DependencyObject, IDmtpActor
|
||||
else//不允许连接
|
||||
{
|
||||
waitVerify.Status = 2;
|
||||
waitVerify.Message ??= "Fail";
|
||||
waitVerify.Metadata = args.Metadata;
|
||||
waitVerify.Message = TouchSocketDmtpResource.RemoteRefuse.Format(args.Message);
|
||||
await this.SendJsonObjectAsync(P2_Handshake_Response, waitVerify).ConfigureAwait(EasyTask.ContinueOnCapturedContext);
|
||||
await this.OnClosed(false, args.Message).ConfigureAwait(EasyTask.ContinueOnCapturedContext);
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ public partial interface IDmtpChannel : IAsyncEnumerable<ByteBlock>
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -34,4 +34,4 @@ internal partial class InternalChannel
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -24,8 +24,6 @@ public sealed class WaitVerify : WaitResult
|
||||
/// </summary>
|
||||
public string Token { get; set; }
|
||||
|
||||
//internal volatile bool Handle;
|
||||
|
||||
/// <summary>
|
||||
/// 元数据
|
||||
/// </summary>
|
||||
|
||||
@@ -11,31 +11,28 @@
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using TouchSocket.Core;
|
||||
|
||||
namespace TouchSocket.Dmtp;
|
||||
|
||||
/// <summary>
|
||||
/// Token验证异常
|
||||
/// 表示在令牌验证过程中发生的异常。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TokenVerifyException : Exception
|
||||
public sealed class TokenVerifyException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// 获取与此异常关联的元数据。
|
||||
/// </summary>
|
||||
public TokenVerifyException()
|
||||
{ }
|
||||
public Metadata Metadata { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// 初始化 <see cref="TokenVerifyException"/> 类的新实例。
|
||||
/// </summary>
|
||||
/// <param name="message">异常信息</param>
|
||||
public TokenVerifyException(string message) : base(message) { }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="message">异常信息</param>
|
||||
/// <param name="inner">内部异常</param>
|
||||
public TokenVerifyException(string message, System.Exception inner) : base(message, inner) { }
|
||||
}
|
||||
/// <param name="metadata">与异常关联的元数据。</param>
|
||||
/// <param name="message">描述错误的消息。</param>
|
||||
public TokenVerifyException(Metadata metadata, string message) : base(message)
|
||||
{
|
||||
Metadata = metadata;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,4 +172,4 @@ public static partial class HttpExtensions
|
||||
await FromFileAsync(context.Response, fileInfo, context.Request, fileName, maxSpeed, bufferLen, autoGzip);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -40,4 +40,4 @@ public class HttpFlowOperator : FlowOperator
|
||||
{
|
||||
this.Length = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,9 @@ public class ReadonlyMemoryHttpContent : HttpContent
|
||||
this.m_memory = memory;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取封装的只读内存。
|
||||
/// </summary>
|
||||
public ReadOnlyMemory<byte> Memory => this.m_memory;
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -65,4 +67,4 @@ public class ReadonlyMemoryHttpContent : HttpContent
|
||||
{
|
||||
await writeFunc(this.m_memory).ConfigureAwait(EasyTask.ContinueOnCapturedContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,4 +32,4 @@ public class StringHttpContent : ReadonlyMemoryHttpContent
|
||||
{
|
||||
// 构造函数将字符串内容和编码方式作为参数,将字符串内容转换为字节数组后传递给基类。
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,4 @@ namespace TouchSocket.Http;
|
||||
public interface IMultifileCollection : IEnumerable<IFormFile>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -73,4 +73,4 @@
|
||||
// /// </summary>
|
||||
// InternalServerError = 1011
|
||||
// }
|
||||
//}
|
||||
//}
|
||||
@@ -14,13 +14,38 @@ using TouchSocket.Core;
|
||||
|
||||
namespace TouchSocket.JsonRpc;
|
||||
|
||||
/// <summary>
|
||||
/// 表示一个等待结果的JsonRpc类。
|
||||
/// </summary>
|
||||
public class JsonRpcWaitResult : JsonRpcBase, IWaitResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置错误代码。
|
||||
/// </summary>
|
||||
public int ErrorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置错误消息。
|
||||
/// </summary>
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置消息。
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置结果。
|
||||
/// </summary>
|
||||
public string Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置标识。
|
||||
/// </summary>
|
||||
public int Sign { get => this.Id ?? -1; set => this.Id = value; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置状态。
|
||||
/// </summary>
|
||||
public byte Status { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,4 +70,4 @@ internal class JsonRpcWaitResultConverter : JsonConverter
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,4 +40,4 @@ public static class JsonRpcParserPluginExtension
|
||||
return jsonRpcParserPlugin;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public abstract class NamedPipeClientBase : SetupConfigObject, INamedPipeSession
|
||||
private ValueCounter m_receiveCounter;
|
||||
private InternalReceiver m_receiver;
|
||||
private SingleStreamDataHandlingAdapter m_dataHandlingAdapter;
|
||||
private readonly Lock m_lockForAbort = LockFactory.Create();
|
||||
private readonly Lock m_lockForAbort = new Lock();
|
||||
#endregion 变量
|
||||
|
||||
#region 事件
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract class NamedPipeSessionClientBase : ResolverConfigObject, INamedP
|
||||
{
|
||||
#region 字段
|
||||
|
||||
private readonly Lock m_lockForAbort = LockFactory.Create();
|
||||
private readonly Lock m_lockForAbort = new Lock();
|
||||
private readonly SemaphoreSlim m_semaphoreSlimForSend = new SemaphoreSlim(1, 1);
|
||||
private TouchSocketConfig m_config;
|
||||
private SingleStreamDataHandlingAdapter m_dataHandlingAdapter;
|
||||
|
||||
@@ -37,4 +37,4 @@ public sealed class ReenterableAttribute : Attribute
|
||||
/// 获取一个值,指示是否可重新进入。
|
||||
/// </summary>
|
||||
public bool Reenterable { get; }
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ namespace TouchSocket.Rpc;
|
||||
/// </summary>
|
||||
public abstract class CallContext : DependencyObject, ICallContext
|
||||
{
|
||||
private readonly Lock m_locker = LockFactory.Create();
|
||||
private readonly Lock m_locker = new Lock();
|
||||
private bool m_canceled;
|
||||
private CancellationTokenSource m_tokenSource;
|
||||
|
||||
|
||||
@@ -29,6 +29,17 @@ public sealed class InvokeResult
|
||||
this.Message = status.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 <see cref="InvokeResult"/> 结构的新实例。
|
||||
/// </summary>
|
||||
/// <param name="ex">异常实例。</param>
|
||||
public InvokeResult(Exception ex)
|
||||
{
|
||||
this.Exception = ex;
|
||||
this.Status = InvokeStatus.Exception;
|
||||
this.Message = ex.Message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化 <see cref="InvokeResult"/> 结构的新实例。
|
||||
/// </summary>
|
||||
|
||||
@@ -36,4 +36,4 @@ public abstract class ScopedRpcServer : RpcServer, IScopedRpcServer
|
||||
/// 调用上下文。
|
||||
/// </summary>
|
||||
protected ICallContext CallContext => ((IScopedRpcServer)this).CallContext;
|
||||
}
|
||||
}
|
||||
@@ -45,4 +45,4 @@ public class ConcurrencyRpcDispatcher<TRpcActor, TCallContext> : IRpcDispatcher<
|
||||
|
||||
return EasyTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,4 +38,4 @@ public interface IRpcDispatcher<TRpcActor, TCallContext>
|
||||
/// 获取一个值,指示是否可重新进入。
|
||||
/// </summary>
|
||||
bool Reenterable { get; }
|
||||
}
|
||||
}
|
||||
@@ -34,4 +34,4 @@ public class ImmediateRpcDispatcher<TRpcActor, TCallContext> : IRpcDispatcher<TR
|
||||
// 直接调用传入的函数并传递调用上下文,不进行任何处理或延迟执行。
|
||||
return func(callContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,4 @@ public interface IScopedRpcServer : IRpcServer
|
||||
/// 调用上下文
|
||||
/// </summary>
|
||||
ICallContext CallContext { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -88,11 +88,13 @@ internal sealed class InternalRpcServerProvider : IRpcServerProvider
|
||||
{
|
||||
invokeResult.Status = InvokeStatus.InvocationException;
|
||||
invokeResult.Message = ex.InnerException != null ? "函数内部发生异常,信息:" + ex.InnerException.Message : "函数内部发生异常,信息:未知";
|
||||
invokeResult.Exception = ex.InnerException;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
invokeResult.Status = InvokeStatus.Exception;
|
||||
invokeResult.Message = ex.Message;
|
||||
invokeResult.Exception = ex;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ public abstract class SerialPortClientBase : SetupConfigObject, ISerialPortSessi
|
||||
|
||||
#region 变量
|
||||
|
||||
private readonly Lock m_lockForAbort = LockFactory.Create();
|
||||
private readonly Lock m_lockForAbort = new Lock();
|
||||
private readonly SemaphoreSlim m_semaphoreForConnect = new SemaphoreSlim(1, 1);
|
||||
private SingleStreamDataHandlingAdapter m_dataHandlingAdapter;
|
||||
private bool m_online;
|
||||
|
||||
@@ -20,4 +20,4 @@ namespace TouchSocket.SerialPorts;
|
||||
/// </summary>
|
||||
public interface ISerialPortSession : IClient, IPluginObject, ISetupConfigObject, IOnlineClient, IConnectableClient, IClosableClient
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -22,4 +22,4 @@ internal static partial class ThrowHelper
|
||||
{
|
||||
throw new RpcException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,4 @@ namespace TouchSocket.WebApi;
|
||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class FromBodyAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,4 @@ namespace TouchSocket.WebApi;
|
||||
public sealed class FromFormAttribute : WebApiNameAttribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,4 @@ namespace TouchSocket.WebApi;
|
||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class FromHeaderAttribute : WebApiNameAttribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,4 @@ namespace TouchSocket.WebApi;
|
||||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class FromQueryAttribute : WebApiNameAttribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -26,4 +26,4 @@ public sealed class RegexRouterAttribute : Attribute
|
||||
{
|
||||
this.RegexTemple = regexTemple;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,4 +49,4 @@ internal class WebApiParameterInfo
|
||||
public bool IsFromHeader { get; }
|
||||
public bool IsFromQuery { get; }
|
||||
public RpcParameter Parameter { get; }
|
||||
}
|
||||
}
|
||||
@@ -48,4 +48,4 @@ public class WebApiRequest
|
||||
/// 获取或设置请求的表单数据。
|
||||
/// </summary>
|
||||
public KeyValuePair<string, string>[] Forms { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -78,4 +78,4 @@ public partial class WebApiEventArgs
|
||||
public System.Net.Http.HttpResponseMessage ResponseMessage { get; }
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -33,4 +33,4 @@ public interface IWebApiMapping : IEnumerable<MappingMethod>
|
||||
/// <param name="httpMethod">要匹配的 HTTP 方法。</param>
|
||||
/// <returns>匹配的 RPC 方法。</returns>
|
||||
RpcMethod Match(string url, HttpMethod httpMethod);
|
||||
}
|
||||
}
|
||||
@@ -54,4 +54,4 @@ public readonly struct MappingMethod
|
||||
/// 获取一个值,该值指示URL是否为正则表达式。
|
||||
/// </summary>
|
||||
public bool IsRegex { get; }
|
||||
}
|
||||
}
|
||||
@@ -24,5 +24,4 @@ namespace TouchSocket.WebApi;
|
||||
internal partial class WebApiSystemTextJsonSerializerContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -23,4 +23,4 @@ public abstract class WebApiNameAttribute : Attribute
|
||||
/// 获取或设置 Web API 的名称。
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -19,4 +19,4 @@ namespace TouchSocket.Sockets;
|
||||
public interface INatService<TClient> : ITcpServiceBase<TClient> where TClient : INatSessionClient
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public abstract partial class TcpClientBase : SetupConfigObject, ITcpSession
|
||||
|
||||
#region 变量
|
||||
|
||||
private readonly Lock m_lockForAbort = LockFactory.Create();
|
||||
private readonly Lock m_lockForAbort = new Lock();
|
||||
private readonly SemaphoreSlim m_semaphoreForConnect = new SemaphoreSlim(1, 1);
|
||||
private readonly TcpCore m_tcpCore = new TcpCore();
|
||||
private Task m_beginReceiveTask;
|
||||
|
||||
@@ -203,4 +203,4 @@ public partial class TcpClientBase
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TouchSocket.Core;
|
||||
using TouchSocket.Resources;
|
||||
@@ -50,7 +51,7 @@ public abstract class TcpSessionClientBase : ResolverConfigObject, ITcpSession,
|
||||
|
||||
#region 变量
|
||||
|
||||
private readonly Lock m_lockForAbort = LockFactory.Create();
|
||||
private readonly Lock m_lockForAbort = new Lock();
|
||||
private Task m_beginReceiveTask;
|
||||
private SingleStreamDataHandlingAdapter m_dataHandlingAdapter;
|
||||
private string m_id;
|
||||
|
||||
@@ -38,4 +38,4 @@ public class UdpSendingEventArgs : SendingEventArgs
|
||||
/// 获取发送数据的目的端点。
|
||||
/// </summary>
|
||||
public EndPoint EndPoint { get; }
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,4 @@ namespace TouchSocket.Sockets;
|
||||
/// </summary>
|
||||
public interface IUdpSessionBase : IServiceBase, IClient
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -30,4 +30,4 @@ public interface IUdpSendingPlugin : IPlugin
|
||||
/// <param name="e">包含发送事件相关数据的参数对象。</param>
|
||||
/// <returns>一个Task对象,代表异步操作的结果。</returns>
|
||||
Task OnUdpSending(IUdpSessionBase client, UdpSendingEventArgs e);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本:4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能会导致不正确的行为,并且如果
|
||||
// 重新生成代码,这些更改将会丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
|
||||
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
|
||||
// CSDN博客:https://blog.csdn.net/qq_40374647
|
||||
// 哔哩哔哩视频:https://space.bilibili.com/94253567
|
||||
// Gitee源代码仓库:https://gitee.com/RRQM_Home
|
||||
// Github源代码仓库:https://github.com/RRQM
|
||||
// API首页:https://touchsocket.net/
|
||||
// 交流QQ群:234762506
|
||||
// 感谢您的下载和使用
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace TouchSocket.Resources {
|
||||
@@ -186,4 +188,4 @@ namespace TouchSocket.Resources {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user