From 301beda2a224da3591c0c7aeaf9dd459b844b608 Mon Sep 17 00:00:00 2001
From: "2248356998 qq.com" <2248356998@qq.com>
Date: Mon, 13 Oct 2025 21:10:39 +0800
Subject: [PATCH] build: 10.11.98
---
.../ThingsGateway.Admin.Application.csproj | 2 +-
.../Common/ExpiringDictionary.cs | 121 ++++++-
.../Reflection/Reflect.cs | 12 +-
.../Threading/TimerX.cs | 6 +-
src/Directory.Build.props | 8 +-
.../ThingsGateway.Gateway.Application.csproj | 2 +-
.../Variable/VariableRuntimeInfo.razor | 2 +-
.../Variable/VariableRuntimeInfo.razor.cs | 44 ++-
.../Slave/ModbusSlave.cs | 322 +++++++++---------
9 files changed, 297 insertions(+), 222 deletions(-)
diff --git a/src/Admin/ThingsGateway.Admin.Application/ThingsGateway.Admin.Application.csproj b/src/Admin/ThingsGateway.Admin.Application/ThingsGateway.Admin.Application.csproj
index de1d301dc..1fdd773b3 100644
--- a/src/Admin/ThingsGateway.Admin.Application/ThingsGateway.Admin.Application.csproj
+++ b/src/Admin/ThingsGateway.Admin.Application/ThingsGateway.Admin.Application.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/src/Admin/ThingsGateway.NewLife.X/Common/ExpiringDictionary.cs b/src/Admin/ThingsGateway.NewLife.X/Common/ExpiringDictionary.cs
index 4caa54ffc..e20ed8780 100644
--- a/src/Admin/ThingsGateway.NewLife.X/Common/ExpiringDictionary.cs
+++ b/src/Admin/ThingsGateway.NewLife.X/Common/ExpiringDictionary.cs
@@ -5,30 +5,101 @@ namespace ThingsGateway.NewLife;
public class ExpiringDictionary : IDisposable
{
- private ConcurrentDictionary _dict = new();
- private readonly TimerX _cleanupTimer;
-
- public ExpiringDictionary(int cleanupInterval = 60000)
+ /// 缓存项
+ public class CacheItem
{
- _cleanupTimer = new TimerX(Clear, null, cleanupInterval, cleanupInterval) { Async = true };
+ private TValue? _value;
+ /// 数值
+ public TValue? Value { get => _value; }
+
+ /// 过期时间。系统启动以来的毫秒数
+ public Int64 ExpiredTime { get; set; }
+
+ /// 是否过期
+ public Boolean Expired => ExpiredTime <= Runtime.TickCount64;
+
+ /// 访问时间
+ public Int64 VisitTime { get; private set; }
+
+ /// 构造缓存项
+ ///
+ ///
+ public CacheItem(TValue? value, Int32 expire) => Set(value, expire);
+
+ /// 设置数值和过期时间
+ ///
+ /// 过期时间,秒
+ public void Set(TValue value, Int32 expire)
+ {
+ _value = value;
+
+ var now = VisitTime = Runtime.TickCount64;
+ if (expire <= 0)
+ ExpiredTime = Int64.MaxValue;
+ else
+ ExpiredTime = now + expire * 1000L;
+ }
+
+ /// 更新访问时间并返回数值
+ ///
+ public TValue? Visit()
+ {
+ VisitTime = Runtime.TickCount64;
+ var rs = _value;
+ if (rs == null) return default;
+
+ return rs;
+ }
}
- public void TryAdd(TKey key, TValue value)
+ private ConcurrentDictionary _dict = new();
+ private readonly TimerX _cleanupTimer;
+ private int defaultExpire = 60;
+ public ExpiringDictionary(int expire = 60)
{
- _dict.TryAdd(key, value);
+ defaultExpire = expire;
+ _cleanupTimer = new TimerX(TimerClear, null, 10000, 10000) { Async = true };
+ }
+
+
+
+ public bool TryAdd(TKey key, TValue value)
+ {
+ if (_dict.TryGetValue(key, out var item))
+ {
+ if (!item.Expired) return false;
+ item.Set(value, defaultExpire);
+ return true;
+ }
+ return _dict.TryAdd(key, new CacheItem(value, defaultExpire));
}
public bool TryGetValue(TKey key, out TValue value)
{
- return _dict.TryGetValue(key, out value);
+ value = default;
+
+ // 没有值,直接结束
+ if (!_dict.TryGetValue(key, out var item) || item == null) return false;
+
+ // 得到已有值
+ value = item.Visit();
+
+ // 是否未过期的有效值
+ return !item.Expired;
}
public TValue GetOrAdd(TKey key, Func func)
{
- return _dict.GetOrAdd(key, func);
- }
- public TValue GetOrAdd(TKey key, TValue value)
- {
- return _dict.GetOrAdd(key, value);
+ CacheItem? item = null;
+ do
+ {
+ if (_dict.TryGetValue(key, out item) && item != null) return item.Visit();
+
+ item ??= new CacheItem(func(key), defaultExpire);
+ }
+ while (!_dict.TryAdd(key, item));
+
+ return item.Visit();
+
}
public bool TryRemove(TKey key) => _dict.TryRemove(key, out _);
@@ -41,7 +112,31 @@ public class ExpiringDictionary : IDisposable
_dict = new();
data.Clear();
}
+ private void TimerClear(object? state)
+ {
+ var dic = _dict;
+ if (dic.IsEmpty) return;
+
+ // 60分钟之内过期的数据,进入LRU淘汰
+ var now = Runtime.TickCount64;
+
+ // 这里先计算,性能很重要
+ var toDels = new List();
+ foreach (var item in dic)
+ {
+ // 已过期,准备删除
+ var ci = item.Value;
+ if (ci.ExpiredTime <= now)
+ toDels.Add(item.Key);
+ }
+
+ // 确认删除
+ foreach (var item in toDels)
+ {
+ _dict.Remove(item);
+ }
+ }
public void Dispose()
{
_dict.Clear();
diff --git a/src/Admin/ThingsGateway.NewLife.X/Reflection/Reflect.cs b/src/Admin/ThingsGateway.NewLife.X/Reflection/Reflect.cs
index 895d30a1a..f7b290317 100644
--- a/src/Admin/ThingsGateway.NewLife.X/Reflection/Reflect.cs
+++ b/src/Admin/ThingsGateway.NewLife.X/Reflection/Reflect.cs
@@ -561,7 +561,7 @@ public static class Reflect
///
///
///
- public static TFunc? As(this MethodInfo method, object? target = null)
+ public static TFunc? As(this MethodInfo method, object? target = null) where TFunc : class
{
if (method == null) return default;
@@ -569,10 +569,14 @@ public static class Reflect
var func = DelegateCache.Cache.GetOrAdd(
key,
- _ => (TFunc)(object)(
+ _ =>
+ {
+ return (
target == null
- ? Delegate.CreateDelegate(typeof(TFunc), method, true)
- : Delegate.CreateDelegate(typeof(TFunc), target, method, true)));
+ ? Delegate.CreateDelegate(typeof(TFunc), method, true) as TFunc
+ : Delegate.CreateDelegate(typeof(TFunc), target, method, true) as TFunc
+ );
+ });
return func;
}
diff --git a/src/Admin/ThingsGateway.NewLife.X/Threading/TimerX.cs b/src/Admin/ThingsGateway.NewLife.X/Threading/TimerX.cs
index b4144e9e7..b4c5c7041 100644
--- a/src/Admin/ThingsGateway.NewLife.X/Threading/TimerX.cs
+++ b/src/Admin/ThingsGateway.NewLife.X/Threading/TimerX.cs
@@ -391,11 +391,7 @@ public class TimerX : ITimer, ITimerx, IDisposable
// 释放非托管资源
Scheduler?.Remove(this, disposing ? "Dispose" : "GC");
- DelegateCache.Cache.Clear();
-#if NET6_0_OR_GREATER
- DelegateCache>.Cache.Clear();
-#endif
- DelegateCache>.Cache.Clear();
+
}
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 6b6d137d4..29468617f 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,9 +1,9 @@
- 10.11.97
- 10.11.97
- 10.11.97
+ 10.11.98
+ 10.11.98
+ 10.11.98
10.11.6
10.11.6
8.0.20
@@ -12,7 +12,7 @@
false
10.11.87
10.11.87
- 4.0.0-beta.115
+ 4.0.0-beta.120
diff --git a/src/Gateway/ThingsGateway.Gateway.Application/ThingsGateway.Gateway.Application.csproj b/src/Gateway/ThingsGateway.Gateway.Application/ThingsGateway.Gateway.Application.csproj
index cf6c45519..8687c0712 100644
--- a/src/Gateway/ThingsGateway.Gateway.Application/ThingsGateway.Gateway.Application.csproj
+++ b/src/Gateway/ThingsGateway.Gateway.Application/ThingsGateway.Gateway.Application.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Variable/VariableRuntimeInfo.razor b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Variable/VariableRuntimeInfo.razor
index 9a892aea5..e7d73593e 100644
--- a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Variable/VariableRuntimeInfo.razor
+++ b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Variable/VariableRuntimeInfo.razor
@@ -21,7 +21,7 @@
ShowToolbar="true"
ShowExportButton
IsAutoRefresh
- AutoRefreshInterval="2000"
+ AutoRefreshInterval="1000"
ShowDefaultButtons=true
ShowSearch=false
ExtendButtonColumnWidth=220
diff --git a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Variable/VariableRuntimeInfo.razor.cs b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Variable/VariableRuntimeInfo.razor.cs
index 9802cd965..15760b3d4 100644
--- a/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Variable/VariableRuntimeInfo.razor.cs
+++ b/src/Gateway/ThingsGateway.Gateway.Razor/Pages/GatewayMonitorPage/Variable/VariableRuntimeInfo.razor.cs
@@ -55,11 +55,11 @@ public partial class VariableRuntimeInfo : IDisposable
scheduler = new SmartTriggerScheduler(Notify, TimeSpan.FromMilliseconds(1000));
#if !Management
- _ = RunTimerAsync();
+ //timer = new TimerX(RunTimerAsync, null, 1000, 1000) { Async = true };
#endif
base.OnInitialized();
}
-
+ //private TimerX timer;
///
/// IntFormatter
///
@@ -92,27 +92,23 @@ public partial class VariableRuntimeInfo : IDisposable
await InvokeAsync(table.QueryAsync);
}
- private async Task RunTimerAsync()
- {
- while (!Disposed)
- {
- try
- {
- //if (table != null)
- // await table.QueryAsync();
+ //private async Task RunTimerAsync(object? state)
+ //{
+ // try
+ // {
+ // //if (table != null)
+ // // await InvokeAsync(() => table.RowElementRefresh());
- await InvokeAsync(StateHasChanged);
- }
- catch (Exception ex)
- {
- NewLife.Log.XTrace.WriteException(ex);
- }
- finally
- {
- await Task.Delay(1000);
- }
- }
- }
+ // await InvokeAsync(StateHasChanged);
+ // }
+ // catch (Exception ex)
+ // {
+ // NewLife.Log.XTrace.WriteException(ex);
+ // }
+ // finally
+ // {
+ // }
+ //}
#region 查询
@@ -126,7 +122,7 @@ public partial class VariableRuntimeInfo : IDisposable
return data;
#else
var data = Items
- .WhereIf(!options.SearchText.IsNullOrWhiteSpace(), a => a.Name.Contains(options.SearchText))
+ .WhereIf(!string.IsNullOrWhiteSpace(options.SearchText), a => a.Name.Contains(options.SearchText))
.GetQueryData(options);
_option = options;
return Task.FromResult(data);
@@ -354,7 +350,7 @@ public partial class VariableRuntimeInfo : IDisposable
#if !Management
var models = Items
- .WhereIf(!_option.SearchText.IsNullOrWhiteSpace(), a => a.Name.Contains(_option.SearchText)).GetData(_option, out var total).Cast().ToList();
+ .WhereIf(!string.IsNullOrWhiteSpace(_option.SearchText), a => a.Name.Contains(_option.SearchText)).GetData(_option, out var total).Cast().ToList();
#else
diff --git a/src/Plugin/ThingsGateway.Foundation.Modbus/Slave/ModbusSlave.cs b/src/Plugin/ThingsGateway.Foundation.Modbus/Slave/ModbusSlave.cs
index 162593133..6472503a7 100644
--- a/src/Plugin/ThingsGateway.Foundation.Modbus/Slave/ModbusSlave.cs
+++ b/src/Plugin/ThingsGateway.Foundation.Modbus/Slave/ModbusSlave.cs
@@ -516,185 +516,169 @@ public class ModbusSlave : DeviceBase, IModbusAddress
return new OperResult(ex);
}
}
-
- ///
- protected override async Task ChannelReceived(IClientChannel client, ReceivedDataEventArgs e, bool last)
+ protected override Task ChannelReceived(IClientChannel client, ReceivedDataEventArgs e, bool last)
{
- var requestInfo = e.RequestInfo;
- bool modbusRtu = false;
- ModbusRequest modbusRequest = default;
- ReadOnlySequence readOnlySequences = default;
- //接收外部报文
- if (requestInfo is ModbusRtuSlaveMessage modbusRtuSlaveMessage)
+ return HandleChannelReceivedAsync(client, e, last);
+ }
+
+ private async Task HandleChannelReceivedAsync(IClientChannel client, ReceivedDataEventArgs e, bool last)
+ {
+ if (!TryParseRequest(e.RequestInfo, out var modbusRequest, out var sequences, out var modbusRtu))
+ return;
+
+ if (!MulStation && modbusRequest.Station != Station)
+ return;
+
+ var function = NormalizeFunctionCode(modbusRequest.FunctionCode);
+
+ if (function <= 4)
+ await HandleReadRequestAsync(client, e, modbusRequest, sequences, modbusRtu).ConfigureAwait(false);
+ else
+ await HandleWriteRequestAsync(client, e, modbusRequest, sequences, modbusRtu, function).ConfigureAwait(false);
+ }
+
+ private static bool TryParseRequest(object requestInfo, out ModbusRequest modbusRequest, out ReadOnlySequence sequences, out bool modbusRtu)
+ {
+ modbusRequest = default;
+ sequences = default;
+ modbusRtu = false;
+
+ switch (requestInfo)
{
- if (!modbusRtuSlaveMessage.IsSuccess)
- {
- return;
- }
- modbusRequest = modbusRtuSlaveMessage.Request;
- readOnlySequences = modbusRtuSlaveMessage.Sequences;
- modbusRtu = true;
+ case ModbusRtuSlaveMessage rtuMsg when rtuMsg.IsSuccess:
+ modbusRequest = rtuMsg.Request;
+ sequences = rtuMsg.Sequences;
+ modbusRtu = true;
+ return true;
+
+ case ModbusTcpSlaveMessage tcpMsg when tcpMsg.IsSuccess:
+ modbusRequest = tcpMsg.Request;
+ sequences = tcpMsg.Sequences;
+ modbusRtu = false;
+ return true;
+
+ default:
+ return false;
}
- else if (requestInfo is ModbusTcpSlaveMessage modbusTcpSlaveMessage)
+ }
+
+ private static byte NormalizeFunctionCode(byte funcCode)
+ => funcCode > 0x30 ? (byte)(funcCode - 0x30) : funcCode;
+
+ private async Task HandleReadRequestAsync(
+ IClientChannel client,
+ ReceivedDataEventArgs e,
+ ModbusRequest modbusRequest,
+ ReadOnlySequence sequences,
+ bool modbusRtu)
+ {
+ var data = ModbusRequest(modbusRequest, true);
+ if (!data.IsSuccess)
{
- if (!modbusTcpSlaveMessage.IsSuccess)
- {
+ await WriteError(modbusRtu, client, sequences, e).ConfigureAwait(false);
+ return;
+ }
+
+ ValueByteBlock byteBlock = new(1024);
+ try
+ {
+ WriteReadResponse(modbusRequest, sequences, data.Content, ref byteBlock, modbusRtu);
+ await ReturnData(client, byteBlock.Memory, e).ConfigureAwait(false);
+ }
+ catch
+ {
+ await WriteError(modbusRtu, client, sequences, e).ConfigureAwait(false);
+ }
+ finally
+ {
+ byteBlock.SafeDispose();
+ }
+ }
+
+ private async Task HandleWriteRequestAsync(
+ IClientChannel client,
+ ReceivedDataEventArgs e,
+ ModbusRequest modbusRequest,
+ ReadOnlySequence sequences,
+ bool modbusRtu,
+ byte f)
+ {
+ var modbusAddress = new ModbusAddress(modbusRequest);
+ bool isSuccess;
+
+ switch (f)
+ {
+ case 5:
+ case 15:
+ modbusAddress.WriteFunctionCode = modbusRequest.FunctionCode;
+ modbusAddress.FunctionCode = 1;
+ isSuccess = await HandleWriteCoreAsync(modbusAddress, client, modbusRequest).ConfigureAwait(false);
+ break;
+
+ case 6:
+ case 16:
+ modbusAddress.WriteFunctionCode = modbusRequest.FunctionCode;
+ modbusAddress.FunctionCode = 3;
+ isSuccess = await HandleWriteCoreAsync(modbusAddress, client, modbusRequest).ConfigureAwait(false);
+ break;
+
+ default:
return;
- }
- modbusRequest = modbusTcpSlaveMessage.Request;
- readOnlySequences = modbusTcpSlaveMessage.Sequences;
- modbusRtu = false;
+ }
+
+ if (isSuccess)
+ await WriteSuccess(modbusRtu, client, sequences, e).ConfigureAwait(false);
+ else
+ await WriteError(modbusRtu, client, sequences, e).ConfigureAwait(false);
+ }
+
+ private async Task HandleWriteCoreAsync(ModbusAddress address, IClientChannel client, ModbusRequest modbusRequest)
+ {
+ if (WriteData != null)
+ {
+ var result = await WriteData(address, ThingsGatewayBitConverter, client).ConfigureAwait(false);
+ if (!result.IsSuccess) return false;
+ }
+
+ if (IsWriteMemory)
+ {
+ var memResult = ModbusRequest(modbusRequest, false);
+ return memResult.IsSuccess;
+ }
+
+ return true;
+ }
+
+ private static void WriteReadResponse(
+ ModbusRequest modbusRequest,
+ ReadOnlySequence sequences,
+ ReadOnlyMemory content,
+ ref ValueByteBlock byteBlock,
+ bool modbusRtu)
+ {
+ if (modbusRtu)
+ ByteBlockExtension.Write(ref byteBlock, sequences.Slice(0, 2));
+ else
+ ByteBlockExtension.Write(ref byteBlock, sequences.Slice(0, 8));
+
+ if (modbusRequest.IsBitFunction)
+ {
+ var bitdata = content.Span.ByteToBool().AsSpan().BoolArrayToByte();
+ var len = (int)Math.Ceiling(modbusRequest.Length / 8.0);
+ var bitWriteData = bitdata.AsMemory().Slice(0, len);
+ WriterExtension.WriteValue(ref byteBlock, (byte)bitWriteData.Length);
+ byteBlock.Write(bitWriteData.Span);
}
else
{
- return;
+ WriterExtension.WriteValue(ref byteBlock, (byte)content.Length);
+ byteBlock.Write(content.Span);
}
- //忽略不同设备地址的报文
- if (!MulStation && modbusRequest.Station != Station)
- {
- return;
- }
- var f = modbusRequest.FunctionCode > 0x30 ? modbusRequest.FunctionCode - 0x30 : modbusRequest.FunctionCode;
- if (f <= 4)
- {
- var data = ModbusRequest(modbusRequest, true);
- if (data.IsSuccess)
- {
- ValueByteBlock byteBlock = new(1024);
- try
- {
- if (modbusRtu)
- {
- ByteBlockExtension.Write(ref byteBlock, readOnlySequences.Slice(0, 2));
- if (modbusRequest.IsBitFunction)
- {
- var bitdata = data.Content.Span.ByteToBool().AsSpan().BoolArrayToByte();
- ReadOnlyMemory bitwritedata = bitdata.Length == (int)Math.Ceiling(modbusRequest.Length / 8.0) ? bitdata.AsMemory() : bitdata.AsMemory().Slice(0, (int)Math.Ceiling(modbusRequest.Length / 8.0));
- WriterExtension.WriteValue(ref byteBlock, (byte)bitwritedata.Length);
- byteBlock.Write(bitwritedata.Span);
- }
- else
- {
- WriterExtension.WriteValue(ref byteBlock, (byte)data.Content.Length);
- byteBlock.Write(data.Content.Span);
- }
- byteBlock.Write(CRC16Utils.Crc16Only(byteBlock.Memory.Span));
- await ReturnData(client, byteBlock.Memory, e).ConfigureAwait(false);
- }
- else
- {
- ByteBlockExtension.Write(ref byteBlock, readOnlySequences.Slice(0, 8));
- if (modbusRequest.IsBitFunction)
- {
- var bitdata = data.Content.Span.ByteToBool().AsSpan().BoolArrayToByte();
- ReadOnlyMemory bitwritedata = bitdata.Length == (int)Math.Ceiling(modbusRequest.Length / 8.0) ? bitdata.AsMemory() : bitdata.AsMemory().Slice(0, (int)Math.Ceiling(modbusRequest.Length / 8.0));
- WriterExtension.WriteValue(ref byteBlock, (byte)bitwritedata.Length);
- byteBlock.Write(bitwritedata.Span);
- }
- else
- {
- WriterExtension.WriteValue(ref byteBlock, (byte)data.Content.Length);
- byteBlock.Write(data.Content.Span);
- }
- ByteBlockExtension.WriteBackValue(ref byteBlock, (byte)(byteBlock.Length - 6), EndianType.Big, 5);
- await ReturnData(client, byteBlock.Memory, e).ConfigureAwait(false);
- }
- }
- catch
- {
- await WriteError(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- finally
- {
- byteBlock.SafeDispose();
- }
- }
- else
- {
- await WriteError(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);//返回错误码
- }
- }
- else//写入
- {
- if (f == 5 || f == 15)
- {
- //写入继电器
- if (WriteData != null)
- {
- var modbusAddress = new ModbusAddress(modbusRequest) { WriteFunctionCode = modbusRequest.FunctionCode, FunctionCode = 1 };
- // 接收外部写入时,传出变量地址/写入字节组/转换规则/客户端
- if ((await WriteData(modbusAddress, ThingsGatewayBitConverter, client).ConfigureAwait(false)).IsSuccess)
- {
- await WriteSuccess(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- if (IsWriteMemory)
- {
- var result = ModbusRequest(modbusRequest, false);
- if (result.IsSuccess)
- await WriteSuccess(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- else
- await WriteError(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- else
- await WriteSuccess(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- else
- {
- await WriteError(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- }
- else
- {
- //写入内存区
- var result = ModbusRequest(modbusRequest, false);
- if (result.IsSuccess)
- {
- await WriteSuccess(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- else
- {
- await WriteError(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- }
- }
- else if (f == 6 || f == 16)
- {
- //写入寄存器
- if (WriteData != null)
- {
- var modbusAddress = new ModbusAddress(modbusRequest) { WriteFunctionCode = modbusRequest.FunctionCode, FunctionCode = 3 };
- if ((await WriteData(modbusAddress, ThingsGatewayBitConverter, client).ConfigureAwait(false)).IsSuccess)
- {
- if (IsWriteMemory)
- {
- var result = ModbusRequest(modbusRequest, false);
- if (result.IsSuccess)
- await WriteSuccess(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- else
- await WriteError(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- else
- await WriteSuccess(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- else
- {
- await WriteError(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- }
- else
- {
- var result = ModbusRequest(modbusRequest, false);
- if (result.IsSuccess)
- {
- await WriteSuccess(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- else
- {
- await WriteError(modbusRtu, client, readOnlySequences, e).ConfigureAwait(false);
- }
- }
- }
- }
+ if (modbusRtu)
+ byteBlock.Write(CRC16Utils.Crc16Only(byteBlock.Memory.Span));
+ else
+ ByteBlockExtension.WriteBackValue(ref byteBlock, (byte)(byteBlock.Length - 6), EndianType.Big, 5);
}
private async Task ReturnData(IClientChannel client, ReadOnlyMemory sendData, ReceivedDataEventArgs e)