Compare commits

..

2 Commits

Author SHA1 Message Date
Diego
8e35c16edf 恢复restart标记 2025-07-18 17:46:56 +08:00
Diego
143b751213 Revert "build: 10.9.42"
This reverts commit 2cafe745b9.
2025-07-18 14:41:19 +08:00
43 changed files with 232 additions and 185 deletions

View File

@@ -17,6 +17,7 @@ using System.Diagnostics;
using System.Net;
using ThingsGateway.HttpRemote.Extensions;
using ThingsGateway.NewLife.Log;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;
@@ -254,7 +255,7 @@ public sealed class ProfilerDelegatingHandler(ILogger<Logging> logger, IOptions<
}
else
{
Console.WriteLine(message);
XTrace.WriteLine(message);
}
}

View File

@@ -16,14 +16,16 @@ namespace ThingsGateway.NewLife;
public sealed class WaitLock : IDisposable
{
private readonly SemaphoreSlim _waiterLock;
private readonly string _name;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="name">名称</param>
/// <param name="maxCount">最大并发数</param>
/// <param name="initialZeroState">初始无信号量</param>
public WaitLock(int maxCount = 1, bool initialZeroState = false)
public WaitLock(string name, int maxCount = 1, bool initialZeroState = false)
{
_name = name;
if (initialZeroState)
_waiterLock = new SemaphoreSlim(0, maxCount);
else
@@ -48,19 +50,27 @@ public sealed class WaitLock : IDisposable
public int CurrentCount => _waiterLock.CurrentCount;
public bool Waitting => _waiterLock.CurrentCount < MaxCount;
private object m_lockObj = new();
/// <summary>
/// 离开锁
/// </summary>
public void Release()
{
if (DisposedValue) return;
try
{
_waiterLock.Release();
}
catch (SemaphoreFullException)
lock (m_lockObj)
{
if (Waitting)
{
try
{
_waiterLock.Release();
}
catch (SemaphoreFullException)
{
}
}
}
}
/// <summary>

View File

@@ -2,6 +2,7 @@
using ThingsGateway.NewLife;
using ThingsGateway.NewLife.Compression;
using ThingsGateway.NewLife.Log;
#if NET8_0_OR_GREATER
using System.Formats.Tar;
@@ -578,7 +579,7 @@ public static class PathHelper
});
if (rs?.Length > 0) list.AddRange(rs);
}
catch (Exception ex) { Console.WriteLine(" " + ex.Message); }
catch (Exception ex) { XTrace.WriteLine(ex.Message); }
}
return list.ToArray();

View File

@@ -1,11 +1,11 @@
<Project>
<PropertyGroup>
<PluginVersion>10.9.42</PluginVersion>
<ProPluginVersion>10.9.42</ProPluginVersion>
<DefaultVersion>10.9.42</DefaultVersion>
<AuthenticationVersion>2.9.19</AuthenticationVersion>
<SourceGeneratorVersion>10.9.19</SourceGeneratorVersion>
<PluginVersion>10.9.44</PluginVersion>
<ProPluginVersion>10.9.44</ProPluginVersion>
<DefaultVersion>10.9.44</DefaultVersion>
<AuthenticationVersion>2.9.20</AuthenticationVersion>
<SourceGeneratorVersion>10.9.20</SourceGeneratorVersion>
<NET8Version>8.0.18</NET8Version>
<NET9Version>9.0.7</NET9Version>
<SatelliteResourceLanguages>zh-Hans;en-US</SatelliteResourceLanguages>

View File

@@ -84,7 +84,7 @@ public partial class LogConsole : IDisposable
Disposed = true;
GC.SuppressFinalize(this);
}
private WaitLock WaitLock = new();
private WaitLock WaitLock = new(nameof(LogConsole));
protected async Task ExecuteAsync()
{
if (WaitLock.Waited) return;

View File

@@ -15,7 +15,7 @@ namespace ThingsGateway.Foundation;
/// <inheritdoc/>
public class ChannelOptions : ChannelOptionsBase, IChannelOptions, IDisposable
{
public WaitLock WaitLock { get; private set; } = new WaitLock();
public WaitLock WaitLock { get; private set; } = new WaitLock(nameof(ChannelOptions));
/// <inheritdoc/>
public override int MaxConcurrentCount
{
@@ -31,7 +31,7 @@ public class ChannelOptions : ChannelOptionsBase, IChannelOptions, IDisposable
if (WaitLock?.MaxCount != MaxConcurrentCount)
{
var _lock = WaitLock;
WaitLock = new WaitLock(_maxConcurrentCount);
WaitLock = new WaitLock(nameof(ChannelOptions), _maxConcurrentCount);
_lock?.SafeDispose();
}
}

View File

@@ -65,7 +65,7 @@ public class DDPTcpSessionClientChannel : TcpSessionClientChannel
private DeviceSingleStreamDataHandleAdapter<DDPTcpMessage> DDPAdapter = new();
private WaitLock _waitLock = new();
private WaitLock _waitLock = new(nameof(DDPTcpSessionClientChannel));
protected override async ValueTask<bool> OnTcpReceiving(ByteBlock byteBlock)
{
DDPMessage? message = null;

View File

@@ -91,7 +91,7 @@ public class DDPUdpSessionChannel : UdpSessionChannel, IClientChannel, IDtuUdpSe
public override WaitLock GetLock(string key)
{
if (key.IsNullOrEmpty()) return WaitLock;
return WaitLocks.GetOrAdd(key, (a) => new WaitLock(WaitLock.MaxCount));
return WaitLocks.GetOrAdd(key, (a) => new WaitLock(nameof(DDPUdpSessionChannel), WaitLock.MaxCount));
}
public override Task<Result> StopAsync(CancellationToken token)
@@ -108,7 +108,7 @@ public class DDPUdpSessionChannel : UdpSessionChannel, IClientChannel, IDtuUdpSe
var byteBlock = e.ByteBlock;
var endPoint = e.EndPoint;
DDPMessage? message = null;
var waitLock = _waitLocks.GetOrAdd(endPoint, new WaitLock());
var waitLock = _waitLocks.GetOrAdd(endPoint, new WaitLock(nameof(DDPUdpSessionChannel)));
try
{
await waitLock.WaitAsync().ConfigureAwait(false);

View File

@@ -61,7 +61,7 @@ public abstract class TcpServiceChannelBase<TClient> : TcpService<TClient>, ITcp
}
}
private readonly WaitLock _connectLock = new WaitLock();
private readonly WaitLock _connectLock = new WaitLock(nameof(TcpServiceChannelBase<TClient>));
/// <inheritdoc/>
public override async Task StartAsync()
{
@@ -280,7 +280,7 @@ public class TcpServiceChannel<TClient> : TcpServiceChannelBase<TClient>, IChann
{
client.ChannelOptions = ChannelOptions;
client.WaitLock = new NewLife.WaitLock(ChannelOptions.WaitLock.MaxCount);
client.WaitLock = new NewLife.WaitLock(nameof(TcpServiceChannelBase<TClient>), ChannelOptions.WaitLock.MaxCount);
base.ClientInitialized(client);

View File

@@ -60,7 +60,7 @@ public class TcpSessionClientChannel : TcpSessionClient, IClientChannel
public WaitHandlePool<MessageBase> WaitHandlePool { get; private set; } = new();
/// <inheritdoc/>
public WaitLock WaitLock { get; internal set; } = new();
public WaitLock WaitLock { get; internal set; } = new(nameof(TcpSessionClientChannel));
public virtual WaitLock GetLock(string key) => WaitLock;
/// <inheritdoc/>

View File

@@ -19,7 +19,7 @@ namespace ThingsGateway.Foundation;
/// </summary>
public class UdpSessionChannel : UdpSession, IClientChannel
{
private readonly WaitLock _connectLock = new WaitLock();
private readonly WaitLock _connectLock = new WaitLock(nameof(UdpSessionChannel));
/// <inheritdoc/>
public UdpSessionChannel(IChannelOptions channelOptions)

View File

@@ -389,7 +389,7 @@ public abstract class DeviceBase : DisposableObject, IDevice
}
private WaitLock connectWaitLock = new();
private WaitLock connectWaitLock = new(nameof(DeviceBase));
public async Task ConnectAsync(CancellationToken token)
{
@@ -421,9 +421,7 @@ public abstract class DeviceBase : DisposableObject, IDevice
var dtuId = this is IDtu dtu1 ? dtu1.DtuId : null;
var channelResult = GetChannel(dtuId);
if (!channelResult.IsSuccess) return new OperResult<byte[]>(channelResult);
WaitLock? waitLock = null;
EndPoint? endPoint = GetUdpEndpoint(dtuId);
waitLock = GetWaitLock(channelResult.Content, waitLock, dtuId);
WaitLock? waitLock = GetWaitLock(channelResult.Content, dtuId);
try
{
@@ -434,6 +432,8 @@ public abstract class DeviceBase : DisposableObject, IDevice
if (channelResult.Content.ReadOnlyDataHandlingAdapter != null)
channelResult.Content.ReadOnlyDataHandlingAdapter.Logger = Logger;
EndPoint? endPoint = GetUdpEndpoint(dtuId);
return await SendAsync(sendMessage, channelResult.Content, endPoint, cancellationToken).ConfigureAwait(false);
}
finally
@@ -548,37 +548,38 @@ public abstract class DeviceBase : DisposableObject, IDevice
var waitData = clientChannel.WaitHandlePool.GetWaitDataAsync(out var sign);
command.Sign = sign;
WaitLock? waitLock = null;
var dtuId = this is IDtu dtu1 ? dtu1.DtuId : null;
EndPoint? endPoint = GetUdpEndpoint(dtuId);
try
{
waitLock = GetWaitLock(clientChannel, waitLock, dtuId);
var dtuId = this is IDtu dtu1 ? dtu1.DtuId : null;
waitLock = GetWaitLock(clientChannel, dtuId);
await BefortSendAsync(clientChannel, cancellationToken).ConfigureAwait(false);
await waitLock.WaitAsync(cancellationToken).ConfigureAwait(false);
if (clientChannel.ReadOnlyDataHandlingAdapter != null)
clientChannel.ReadOnlyDataHandlingAdapter.Logger = Logger;
EndPoint? endPoint = GetUdpEndpoint(dtuId);
if (cancellationToken.IsCancellationRequested)
return new MessageBase(new OperationCanceledException());
waitData.SetCancellationToken(cancellationToken);
if (clientChannel.ReadOnlyDataHandlingAdapter != null)
clientChannel.ReadOnlyDataHandlingAdapter.Logger = Logger;
Channel.ChannelReceivedWaitDict.TryAdd(sign, ChannelReceived);
if (cancellationToken.IsCancellationRequested)
return new MessageBase(new OperationCanceledException());
var sendOperResult = await SendAsync(command, clientChannel, endPoint, cancellationToken).ConfigureAwait(false);
if (!sendOperResult.IsSuccess)
throw sendOperResult.Exception ?? new(sendOperResult.ErrorMessage ?? "unknown error");
await waitData.WaitAsync(timeout).ConfigureAwait(false);
waitData.SetCancellationToken(cancellationToken);
if (cancellationToken.IsCancellationRequested)
{
if (!this.DisposedValue)
{
await Task.Delay(timeout, CancellationToken.None).ConfigureAwait(false);
}
}
await waitData.WaitAsync(timeout).ConfigureAwait(false);
var result = waitData.Check();
if (result.IsSuccess)
@@ -587,20 +588,39 @@ public abstract class DeviceBase : DisposableObject, IDevice
}
else
{
if (cancellationToken.IsCancellationRequested)
{
if (!this.DisposedValue)
{
await Task.Delay(timeout, CancellationToken.None).ConfigureAwait(false);
}
}
return new MessageBase(result);
}
}
catch (Exception ex)
{
if (cancellationToken.IsCancellationRequested)
{
if (!this.DisposedValue)
{
await Task.Delay(timeout, CancellationToken.None).ConfigureAwait(false);
}
}
return new MessageBase(ex);
}
finally
{
waitLock.Release();
clientChannel.WaitHandlePool.Destroy(sign);
Channel.ChannelReceivedWaitDict.TryRemove(sign, out _);
waitLock?.Release();
clientChannel.WaitHandlePool.Destroy(sign);
}
}
private static WaitLock GetWaitLock(IClientChannel clientChannel, WaitLock? waitLock, string dtuId)
private static WaitLock GetWaitLock(IClientChannel clientChannel, string dtuId)
{
WaitLock? waitLock = null;
if (clientChannel is IDtuUdpSessionChannel udpSessionChannel)
{
waitLock = udpSessionChannel.GetLock(dtuId);

View File

@@ -148,9 +148,9 @@ public class ControlController : ControllerBase
/// </summary>
[HttpPost("batchSaveChannel")]
[DisplayName("保存通道")]
public Task<bool> BatchSaveChannelAsync([FromBody] List<ChannelInput> channels, ItemChangedType type)
public Task<bool> BatchSaveChannelAsync([FromBody] List<ChannelInput> channels, ItemChangedType type, bool restart = true)
{
return GlobalData.ChannelRuntimeService.BatchSaveChannelAsync(channels.AdaptListChannel(), type);
return GlobalData.ChannelRuntimeService.BatchSaveChannelAsync(channels.AdaptListChannel(), type, restart);
}
/// <summary>
@@ -158,9 +158,9 @@ public class ControlController : ControllerBase
/// </summary>
[HttpPost("batchSaveDevice")]
[DisplayName("保存设备")]
public Task<bool> BatchSaveDeviceAsync([FromBody] List<DeviceInput> devices, ItemChangedType type)
public Task<bool> BatchSaveDeviceAsync([FromBody] List<DeviceInput> devices, ItemChangedType type, bool restart = true)
{
return GlobalData.DeviceRuntimeService.BatchSaveDeviceAsync(devices.AdaptListDevice(), type);
return GlobalData.DeviceRuntimeService.BatchSaveDeviceAsync(devices.AdaptListDevice(), type, restart);
}
/// <summary>
@@ -168,7 +168,7 @@ public class ControlController : ControllerBase
/// </summary>
[HttpPost("batchSaveVariable")]
[DisplayName("保存变量")]
public Task<bool> BatchSaveVariableAsync([FromBody] List<VariableInput> variables, ItemChangedType type, bool restart)
public Task<bool> BatchSaveVariableAsync([FromBody] List<VariableInput> variables, ItemChangedType type, bool restart = true)
{
return GlobalData.VariableRuntimeService.BatchSaveVariableAsync(variables.AdaptListVariable(), type, restart, default);
}
@@ -178,10 +178,10 @@ public class ControlController : ControllerBase
/// </summary>
[HttpPost("deleteChannel")]
[DisplayName("删除通道")]
public Task<bool> DeleteChannelAsync([FromBody] List<long> ids)
public Task<bool> DeleteChannelAsync([FromBody] List<long> ids, bool restart = true)
{
if (ids == null || ids.Count == 0) ids = GlobalData.IdChannels.Keys.ToList();
return GlobalData.ChannelRuntimeService.DeleteChannelAsync(ids, default);
return GlobalData.ChannelRuntimeService.DeleteChannelAsync(ids, restart, default);
}
@@ -190,10 +190,10 @@ public class ControlController : ControllerBase
/// </summary>
[HttpPost("deleteDevice")]
[DisplayName("删除设备")]
public Task<bool> DeleteDeviceAsync([FromBody] List<long> ids)
public Task<bool> DeleteDeviceAsync([FromBody] List<long> ids, bool restart = true)
{
if (ids == null || ids.Count == 0) ids = GlobalData.IdDevices.Keys.ToList();
return GlobalData.DeviceRuntimeService.DeleteDeviceAsync(ids, default);
return GlobalData.DeviceRuntimeService.DeleteDeviceAsync(ids, restart, default);
}
/// <summary>
@@ -201,7 +201,7 @@ public class ControlController : ControllerBase
/// </summary>
[HttpPost("deleteVariable")]
[DisplayName("删除变量")]
public Task<bool> DeleteVariableAsync([FromBody] List<long> ids, bool restart)
public Task<bool> DeleteVariableAsync([FromBody] List<long> ids, bool restart = true)
{
if (ids == null || ids.Count == 0) ids = GlobalData.IdVariables.Keys.ToList();
return GlobalData.VariableRuntimeService.DeleteVariableAsync(ids, restart, default);
@@ -213,7 +213,7 @@ public class ControlController : ControllerBase
/// </summary>
[HttpPost("insertTestData")]
[DisplayName("增加测试数据")]
public Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart)
public Task InsertTestDataAsync(int testVariableCount, int testDeviceCount, string slaveUrl, bool businessEnable, bool restart = true)
{
return GlobalData.VariableRuntimeService.InsertTestDataAsync(testVariableCount, testDeviceCount, slaveUrl, businessEnable, restart, default);
}

View File

@@ -385,7 +385,7 @@ public abstract class CollectBase : DriverBase, IRpcDriver
//if (LogMessage?.LogLevel <= TouchSocket.Core.LogLevel.Trace)
// LogMessage?.Trace(string.Format("{0} - Collecting [{1} - {2}]", DeviceName, variableSourceRead?.RegisterAddress, variableSourceRead?.Length));
readResult = await ReadSourceAsync(variableSourceRead, cancellationToken).ConfigureAwait(false);
readResult = await ReadSourceAsync(variableSourceRead, allToken).ConfigureAwait(false);
}
if (readResult.IsSuccess)
@@ -571,20 +571,20 @@ public abstract class CollectBase : DriverBase, IRpcDriver
.ToDictionary(item => item.Key, item => item.Value).ToArray();
// 使用并发方式遍历写入信息列表,并进行异步写入操作
await list.ParallelForEachAsync(async (writeInfo, cancellationToken) =>
{
try
{
// 调用协议的写入方法,将写入信息中的数据写入到对应的寄存器地址,并获取操作结果
var result = await InvokeMethodAsync(writeInfo.Key.VariableMethod, writeInfo.Value?.ToString(), false, cancellationToken).ConfigureAwait(false);
try
{
// 调用协议的写入方法,将写入信息中的数据写入到对应的寄存器地址,并获取操作结果
var result = await InvokeMethodAsync(writeInfo.Key.VariableMethod, writeInfo.Value?.ToString(), false, cancellationToken).ConfigureAwait(false);
// 将操作结果添加到结果字典中,使用变量名称作为键
operResults.TryAdd(writeInfo.Key.Name, result);
}
catch (Exception ex)
{
operResults.TryAdd(writeInfo.Key.Name, new(ex));
}
}, CollectProperties.MaxConcurrentCount, cancellationToken).ConfigureAwait(false);
// 将操作结果添加到结果字典中,使用变量名称作为键
operResults.TryAdd(writeInfo.Key.Name, result);
}
catch (Exception ex)
{
operResults.TryAdd(writeInfo.Key.Name, new(ex));
}
}, CollectProperties.MaxConcurrentCount, cancellationToken).ConfigureAwait(false);
}
finally
{

View File

@@ -147,7 +147,7 @@ public abstract class DriverBase : DisposableObject, IDriver
#region
private WaitLock SetLogLock = new();
private WaitLock SetLogLock = new(nameof(DriverBase));
public async Task SetLogAsync(LogLevel? logLevel = null, bool upDataBase = true)
{
try
@@ -354,6 +354,7 @@ public abstract class DriverBase : DisposableObject, IDriver
protected override void Dispose(bool disposing)
{
TaskSchedulerLoop?.Stop();
TextLogger?.Dispose();
_logger?.TryDispose();
IdVariableRuntimes?.Clear();
@@ -362,6 +363,7 @@ public abstract class DriverBase : DisposableObject, IDriver
if (device != null)
device.Driver = null;
LogMessage?.Logs?.ForEach(a => a.TryDispose());
LogMessage = null;
pluginPropertyEditorItems?.Clear();

View File

@@ -49,7 +49,7 @@ public class ChannelRuntime : Channel, IChannelOptions, IDisposable
[Newtonsoft.Json.JsonIgnore]
[MapperIgnore]
[AutoGenerateColumn(Ignore = true)]
public WaitLock WaitLock { get; private set; } = new WaitLock();
public WaitLock WaitLock { get; private set; } = new WaitLock(nameof(ChannelRuntime));
/// <inheritdoc/>
[MinValue(1)]
@@ -68,7 +68,7 @@ public class ChannelRuntime : Channel, IChannelOptions, IDisposable
if (WaitLock?.MaxCount != MaxConcurrentCount)
{
var _lock = WaitLock;
WaitLock = new WaitLock(_maxConcurrentCount);
WaitLock = new WaitLock(nameof(ChannelRuntime), _maxConcurrentCount);
_lock?.SafeDispose();
}
}

View File

@@ -24,9 +24,9 @@ public class ChannelRuntimeService : IChannelRuntimeService
{
_logger = logger;
}
private WaitLock WaitLock { get; set; } = new WaitLock();
private WaitLock WaitLock { get; set; } = new WaitLock(nameof(ChannelRuntimeService));
public async Task<bool> CopyAsync(List<Channel> models, Dictionary<Device, List<Variable>> devices, CancellationToken cancellationToken)
public async Task<bool> CopyAsync(List<Channel> models, Dictionary<Device, List<Variable>> devices, bool restart, CancellationToken cancellationToken)
{
try
{
@@ -43,7 +43,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
await RuntimeServiceHelper.InitAsync(newChannelRuntimes, newDeviceRuntimes, _logger).ConfigureAwait(false);
//根据条件重启通道线程
//if (restart)
if (restart)
{
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
@@ -59,7 +59,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
}
}
public async Task<bool> InsertAsync(List<Channel> models, List<Device> devices, List<Variable> variables, CancellationToken cancellationToken)
public async Task<bool> InsertAsync(List<Channel> models, List<Device> devices, List<Variable> variables, bool restart, CancellationToken cancellationToken)
{
try
{
@@ -76,7 +76,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
await RuntimeServiceHelper.InitAsync(newChannelRuntimes, newDeviceRuntimes, _logger).ConfigureAwait(false);
//根据条件重启通道线程
//if (restart)
if (restart)
{
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
@@ -92,7 +92,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
}
}
public async Task<bool> UpdateAsync(List<Channel> models, List<Device> devices, List<Variable> variables, CancellationToken cancellationToken)
public async Task<bool> UpdateAsync(List<Channel> models, List<Device> devices, List<Variable> variables, bool restart, CancellationToken cancellationToken)
{
try
{
@@ -109,7 +109,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
await RuntimeServiceHelper.InitAsync(newChannelRuntimes, newDeviceRuntimes, _logger).ConfigureAwait(false);
//根据条件重启通道线程
//if (restart)
if (restart)
{
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
@@ -125,7 +125,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
}
}
public async Task<bool> BatchEditAsync(IEnumerable<Channel> models, Channel oldModel, Channel model)
public async Task<bool> BatchEditAsync(IEnumerable<Channel> models, Channel oldModel, Channel model, bool restart)
{
try
{
@@ -138,7 +138,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
RuntimeServiceHelper.Init(newChannelRuntimes);
//根据条件重启通道线程
//if (restart)
if (restart)
{
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
}
@@ -151,7 +151,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
}
}
public async Task<bool> DeleteChannelAsync(IEnumerable<long> ids, CancellationToken cancellationToken)
public async Task<bool> DeleteChannelAsync(IEnumerable<long> ids, bool restart, CancellationToken cancellationToken)
{
try
{
@@ -163,7 +163,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
var changedDriver = RuntimeServiceHelper.DeleteChannelRuntime(array);
//根据条件重启通道线程
//if (restart)
if (restart)
{
await GlobalData.ChannelThreadManage.RemoveChannelAsync(array).ConfigureAwait(false);
@@ -186,7 +186,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
public Task<MemoryStream> ExportMemoryStream(IEnumerable<Channel> data) =>
GlobalData.ChannelService.ExportMemoryStream(data);
public async Task ImportChannelAsync(Dictionary<string, ImportPreviewOutputBase> input)
public async Task ImportChannelAsync(Dictionary<string, ImportPreviewOutputBase> input, bool restart)
{
try
{
@@ -199,8 +199,8 @@ public class ChannelRuntimeService : IChannelRuntimeService
RuntimeServiceHelper.Init(newChannelRuntimes);
//根据条件重启通道线程
//if (restart)
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
if (restart)
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
}
@@ -209,7 +209,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
WaitLock.Release();
}
}
public async Task<bool> SaveChannelAsync(Channel input, ItemChangedType type)
public async Task<bool> SaveChannelAsync(Channel input, ItemChangedType type, bool restart)
{
try
{
@@ -222,8 +222,8 @@ public class ChannelRuntimeService : IChannelRuntimeService
RuntimeServiceHelper.Init(newChannelRuntimes);
//根据条件重启通道线程
//if (restart)
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
if (restart)
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
return true;
}
@@ -234,7 +234,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
}
public async Task<bool> BatchSaveChannelAsync(List<Channel> input, ItemChangedType type)
public async Task<bool> BatchSaveChannelAsync(List<Channel> input, ItemChangedType type, bool restart)
{
try
{
@@ -247,8 +247,8 @@ public class ChannelRuntimeService : IChannelRuntimeService
RuntimeServiceHelper.Init(newChannelRuntimes);
//根据条件重启通道线程
//if (restart)
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
if (restart)
await GlobalData.ChannelThreadManage.RestartChannelAsync(newChannelRuntimes).ConfigureAwait(false);
return true;
}

View File

@@ -21,14 +21,16 @@ public interface IChannelRuntimeService
/// </summary>
/// <param name="input">通道对象</param>
/// <param name="type">保存类型</param>
Task<bool> SaveChannelAsync(Channel input, ItemChangedType type);
/// <param name="restart">重启</param>
Task<bool> SaveChannelAsync(Channel input, ItemChangedType type, bool restart);
/// <summary>
/// 保存通道
/// </summary>
/// <param name="input">通道对象</param>
/// <param name="type">保存类型</param>
Task<bool> BatchSaveChannelAsync(List<Channel> input, ItemChangedType type);
/// <param name="restart">重启</param>
Task<bool> BatchSaveChannelAsync(List<Channel> input, ItemChangedType type, bool restart);
/// <summary>
@@ -37,23 +39,24 @@ public interface IChannelRuntimeService
/// <param name="models">列表</param>
/// <param name="oldModel">旧数据</param>
/// <param name="model">新数据</param>
/// <param name="restart">重启</param>
/// <returns></returns>
Task<bool> BatchEditAsync(IEnumerable<Channel> models, Channel oldModel, Channel model);
Task<bool> BatchEditAsync(IEnumerable<Channel> models, Channel oldModel, Channel model, bool restart);
/// <summary>
/// 删除通道
/// </summary>
Task<bool> DeleteChannelAsync(IEnumerable<long> ids, CancellationToken cancellationToken);
Task<bool> DeleteChannelAsync(IEnumerable<long> ids, bool restart, CancellationToken cancellationToken);
/// <summary>
/// 导入通道数据
/// </summary>
Task ImportChannelAsync(Dictionary<string, ImportPreviewOutputBase> input);
Task ImportChannelAsync(Dictionary<string, ImportPreviewOutputBase> input, bool restart);
Task<Dictionary<string, object>> ExportChannelAsync(ExportFilter exportFilter);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile);
Task<MemoryStream> ExportMemoryStream(IEnumerable<Channel> data);
Task RestartChannelAsync(IEnumerable<ChannelRuntime> oldChannelRuntimes);
Task<bool> CopyAsync(List<Channel> models, Dictionary<Device, List<Variable>> devices, CancellationToken cancellationToken);
Task<bool> UpdateAsync(List<Channel> models, List<Device> devices, List<Variable> variables, CancellationToken cancellationToken);
Task<bool> InsertAsync(List<Channel> models, List<Device> devices, List<Variable> variables, CancellationToken cancellationToken);
Task<bool> CopyAsync(List<Channel> models, Dictionary<Device, List<Variable>> devices, bool restart, CancellationToken cancellationToken);
Task<bool> UpdateAsync(List<Channel> models, List<Device> devices, List<Variable> variables, bool restart, CancellationToken cancellationToken);
Task<bool> InsertAsync(List<Channel> models, List<Device> devices, List<Variable> variables, bool restart, CancellationToken cancellationToken);
}

View File

@@ -27,10 +27,10 @@ public class DeviceRuntimeService : IDeviceRuntimeService
_logger = logger;
}
private WaitLock WaitLock { get; set; } = new WaitLock();
private WaitLock WaitLock { get; set; } = new WaitLock(nameof(DeviceRuntimeService));
public async Task<bool> CopyAsync(Dictionary<Device, List<Variable>> devices, CancellationToken cancellationToken)
public async Task<bool> CopyAsync(Dictionary<Device, List<Variable>> devices, bool restart, CancellationToken cancellationToken)
{
try
{
@@ -45,7 +45,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
//根据条件重启通道线程
//if (restart)
if (restart)
{
await RuntimeServiceHelper.RestartDeviceAsync(newDeviceRuntimes).ConfigureAwait(false);
await RuntimeServiceHelper.ChangedDriverAsync(_logger, cancellationToken).ConfigureAwait(false);
@@ -60,7 +60,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
}
}
public async Task<bool> BatchEditAsync(IEnumerable<Device> models, Device oldModel, Device model)
public async Task<bool> BatchEditAsync(IEnumerable<Device> models, Device oldModel, Device model, bool restart)
{
try
{
@@ -71,7 +71,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
var newDeviceRuntimes = await RuntimeServiceHelper.GetNewDeviceRuntimesAsync(deviceids).ConfigureAwait(false);
//if (restart)
if (restart)
{
var newDeciceIds = newDeviceRuntimes.Select(a => a.Id).ToHashSet();
@@ -82,7 +82,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
//根据条件重启通道线程
//if (restart)
if (restart)
{
await RuntimeServiceHelper.RestartDeviceAsync(newDeviceRuntimes).ConfigureAwait(false);
}
@@ -95,7 +95,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
}
}
public async Task<bool> DeleteDeviceAsync(IEnumerable<long> ids, CancellationToken cancellationToken)
public async Task<bool> DeleteDeviceAsync(IEnumerable<long> ids, bool restart, CancellationToken cancellationToken)
{
try
{
@@ -111,7 +111,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
ConcurrentHashSet<IDriver> changedDriver = RuntimeServiceHelper.DeleteDeviceRuntime(deviceRuntimes);
//if (restart)
if (restart)
{
await RuntimeServiceHelper.RemoveDeviceAsync(deviceRuntimes).ConfigureAwait(false);
@@ -136,7 +136,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
GlobalData.DeviceService.ExportMemoryStream(data, channelName, plugin);
public async Task ImportDeviceAsync(Dictionary<string, ImportPreviewOutputBase> input)
public async Task ImportDeviceAsync(Dictionary<string, ImportPreviewOutputBase> input, bool restart)
{
try
{
@@ -146,7 +146,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
var newDeviceRuntimes = await RuntimeServiceHelper.GetNewDeviceRuntimesAsync(deviceids).ConfigureAwait(false);
//if (restart)
if (restart)
{
var newDeciceIds = newDeviceRuntimes.Select(a => a.Id).ToHashSet();
@@ -158,7 +158,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
RuntimeServiceHelper.Init(newDeviceRuntimes);
//根据条件重启通道线程
//if (restart)
if (restart)
{
await RuntimeServiceHelper.RestartDeviceAsync(newDeviceRuntimes).ConfigureAwait(false);
@@ -174,7 +174,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
}
public async Task<bool> SaveDeviceAsync(Device input, ItemChangedType type)
public async Task<bool> SaveDeviceAsync(Device input, ItemChangedType type, bool restart)
{
try
{
@@ -190,7 +190,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
RuntimeServiceHelper.Init(newDeviceRuntimes);
//if (restart)
if (restart)
{
//根据条件重启通道线程
await RuntimeServiceHelper.RestartDeviceAsync(newDeviceRuntimes).ConfigureAwait(false);
@@ -205,7 +205,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
}
public async Task<bool> BatchSaveDeviceAsync(List<Device> input, ItemChangedType type)
public async Task<bool> BatchSaveDeviceAsync(List<Device> input, ItemChangedType type, bool restart)
{
try
@@ -219,7 +219,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
RuntimeServiceHelper.Init(newDeviceRuntimes);
//if (restart)
if (restart)
{
//根据条件重启通道线程
await RuntimeServiceHelper.RestartDeviceAsync(newDeviceRuntimes).ConfigureAwait(false);

View File

@@ -16,14 +16,14 @@ namespace ThingsGateway.Gateway.Application
{
public interface IDeviceRuntimeService
{
Task<bool> BatchEditAsync(IEnumerable<Device> models, Device oldModel, Device model);
Task<bool> CopyAsync(Dictionary<Device, List<Variable>> devices, CancellationToken cancellationToken);
Task<bool> DeleteDeviceAsync(IEnumerable<long> ids, CancellationToken cancellationToken);
Task<bool> BatchEditAsync(IEnumerable<Device> models, Device oldModel, Device model, bool restart);
Task<bool> CopyAsync(Dictionary<Device, List<Variable>> devices, bool restart, CancellationToken cancellationToken);
Task<bool> DeleteDeviceAsync(IEnumerable<long> ids, bool restart, CancellationToken cancellationToken);
Task<Dictionary<string, object>> ExportDeviceAsync(ExportFilter exportFilter);
Task<MemoryStream> ExportMemoryStream(List<Device> data, string channelName, string plugin);
Task ImportDeviceAsync(Dictionary<string, ImportPreviewOutputBase> input);
Task ImportDeviceAsync(Dictionary<string, ImportPreviewOutputBase> input, bool restart);
Task<Dictionary<string, ImportPreviewOutputBase>> PreviewAsync(IBrowserFile browserFile);
Task<bool> SaveDeviceAsync(Device input, ItemChangedType type);
Task<bool> BatchSaveDeviceAsync(List<Device> input, ItemChangedType type);
Task<bool> SaveDeviceAsync(Device input, ItemChangedType type, bool restart);
Task<bool> BatchSaveDeviceAsync(List<Device> input, ItemChangedType type, bool restart);
}
}

View File

@@ -30,7 +30,7 @@ internal sealed class ChannelThreadManage : IChannelThreadManage
#region
private WaitLock NewChannelLock = new();
private WaitLock NewChannelLock = new(nameof(ChannelThreadManage));
/// <summary>
/// 移除指定通道
/// </summary>

View File

@@ -76,7 +76,7 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
#region
private WaitLock SetLogLock = new();
private WaitLock SetLogLock = new(nameof(DeviceThreadManage));
public async Task SetLogAsync(LogLevel? logLevel = null, bool upDataBase = true)
{
try
@@ -171,7 +171,7 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
#region
private WaitLock NewDeviceLock = new();
private WaitLock NewDeviceLock = new(nameof(DeviceThreadManage));
/// <summary>
/// 向当前通道添加设备
@@ -346,8 +346,6 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
CancellationTokenSources.TryAdd(driver.DeviceId, cts);
token.Register(driver.Stop);
_ = Task.Factory.StartNew((state) => DriverStart(state, token), driver, token);
}).ConfigureAwait(false);
@@ -427,22 +425,24 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
}
if (DriverTasks.TryRemove(deviceId, out var task))
{
task.Stop();
}
// 取消驱动程序的操作
if (CancellationTokenSources.TryRemove(deviceId, out var token))
{
if (token != null)
{
driver.Stop();
token.Cancel();
token.Dispose();
}
}
if (DriverTasks.TryRemove(deviceId, out var task))
{
task.Stop();
}
});

View File

@@ -199,7 +199,7 @@ internal sealed class RedundancyTask : IRpcDriver, IAsyncDisposable
}
private WaitLock _switchLock = new();
private WaitLock _switchLock = new(nameof(RedundancyTask));
@@ -424,7 +424,7 @@ internal sealed class RedundancyTask : IRpcDriver, IAsyncDisposable
#region ForcedSync
WaitLock ForcedSyncWaitLock = new WaitLock();
WaitLock ForcedSyncWaitLock = new WaitLock(nameof(RedundancyTask));
public async Task ForcedSync(CancellationToken cancellationToken = default)
{
await ForcedSyncWaitLock.WaitAsync(cancellationToken).ConfigureAwait(false);

View File

@@ -146,8 +146,8 @@ internal sealed partial class ReverseCallbackServer : SingletonRpcServer
}
await GlobalData.ChannelRuntimeService.InsertAsync(addChannels, addDevices, addVariables, default).ConfigureAwait(false);
await GlobalData.ChannelRuntimeService.UpdateAsync(upChannels, upDevices, upVariables, default).ConfigureAwait(false);
await GlobalData.ChannelRuntimeService.InsertAsync(addChannels, addDevices, addVariables, true, default).ConfigureAwait(false);
await GlobalData.ChannelRuntimeService.UpdateAsync(upChannels, upDevices, upVariables, true, default).ConfigureAwait(false);
RedundancyTask.LogMessage?.LogTrace($"Sync data success");

View File

@@ -154,8 +154,8 @@ internal sealed class UpdateZipFileHostedService : BackgroundService, IUpdateZip
return updateZipFiles.OrderByDescending(a => a.Version).ToList();
}
private readonly WaitLock WaitLock = new();
private readonly WaitLock UpdateWaitLock = new();
private readonly WaitLock WaitLock = new(nameof(UpdateZipFileHostedService));
private readonly WaitLock UpdateWaitLock = new(nameof(UpdateZipFileHostedService));
public async Task Update(UpdateZipFile updateZipFile, Func<Task<bool>> check = null)
{
try

View File

@@ -40,7 +40,7 @@ internal sealed class PluginService : IPluginService
private const string DelEx = ".del";
private readonly IDispatchService<PluginInfo> _dispatchService;
private readonly WaitLock _locker = new();
private readonly WaitLock _locker = new(nameof(PluginService));
private readonly ILogger _logger;
public PluginService(ILogger<PluginService> logger, IDispatchService<PluginInfo> dispatchService)

View File

@@ -52,7 +52,7 @@ internal sealed class RulesEngineHostedService : BackgroundService, IRulesEngine
/// <summary>
/// 重启锁
/// </summary>
private WaitLock RestartLock { get; } = new();
private WaitLock RestartLock { get; } = new(nameof(RulesEngineHostedService));
private List<Rules> Rules { get; set; } = new();
public Dictionary<RulesLog, Diagram> Diagrams { get; private set; } = new();

View File

@@ -184,7 +184,7 @@
"Reload": "重载"
},
"ThingsGateway.Gateway.Razor.QuickActions": {
"AutoRestartThread": "变量修改立即生效",
"AutoRestartThread": "自动重启线程",
"HeaderText": "快捷操作",
"ReloadPluginConfirmText": "确定重载插件?",
"ReloadServiceConfirmText": "确定重启运行时?",

View File

@@ -133,7 +133,7 @@ public partial class ChannelTable : IDisposable
{nameof(ChannelCopyComponent.OnSave), async (List<Channel> channels,Dictionary<Device,List<Variable>> devices) =>
{
await Task.Run(() =>GlobalData.ChannelRuntimeService.CopyAsync(channels,devices, default));
await Task.Run(() =>GlobalData.ChannelRuntimeService.CopyAsync(channels,devices,AutoRestartThread, default));
await InvokeAsync(table.QueryAsync);
}},
@@ -174,7 +174,7 @@ public partial class ChannelTable : IDisposable
{
{nameof(ChannelEditComponent.OnValidSubmit), async () =>
{
await Task.Run(() => GlobalData.ChannelRuntimeService.BatchEditAsync(changedModels, oldModel, oneModel));
await Task.Run(() => GlobalData.ChannelRuntimeService.BatchEditAsync(changedModels, oldModel, oneModel,AutoRestartThread));
await InvokeAsync(table.QueryAsync);
@@ -197,7 +197,7 @@ public partial class ChannelTable : IDisposable
{
return await Task.Run(async () =>
{
return await GlobalData.ChannelRuntimeService.DeleteChannelAsync(channels.Select(a => a.Id), default);
return await GlobalData.ChannelRuntimeService.DeleteChannelAsync(channels.Select(a => a.Id), AutoRestartThread, default);
});
}
catch (Exception ex)
@@ -215,7 +215,7 @@ public partial class ChannelTable : IDisposable
try
{
channel = channel.AdaptChannel();
return await Task.Run(() => GlobalData.ChannelRuntimeService.SaveChannelAsync(channel, itemChangedType));
return await Task.Run(() => GlobalData.ChannelRuntimeService.SaveChannelAsync(channel, itemChangedType, AutoRestartThread));
}
catch (Exception ex)
{
@@ -304,7 +304,7 @@ public partial class ChannelTable : IDisposable
await Task.Run(async ()=>
{
var importData=await ChannelServiceHelpers.ImportAsync(data);
await GlobalData.ChannelRuntimeService.ImportChannelAsync(importData);
await GlobalData.ChannelRuntimeService.ImportChannelAsync(importData,AutoRestartThread);
})
;
}
@@ -346,7 +346,7 @@ finally
};
Func<IBrowserFile, Task<Dictionary<string, ImportPreviewOutputBase>>> preview = (a => GlobalData.ChannelRuntimeService.PreviewAsync(a));
Func<Dictionary<string, ImportPreviewOutputBase>, Task> import = (value => GlobalData.ChannelRuntimeService.ImportChannelAsync(value));
Func<Dictionary<string, ImportPreviewOutputBase>, Task> import = (value => GlobalData.ChannelRuntimeService.ImportChannelAsync(value, AutoRestartThread));
op.Component = BootstrapDynamicComponent.CreateComponent<ImportExcel>(new Dictionary<string, object?>
{
{nameof(ImportExcel.Import),import },
@@ -367,7 +367,7 @@ finally
await Task.Run(async () =>
{
await GlobalData.ChannelRuntimeService.DeleteChannelAsync(Items.Select(a => a.Id), default);
await GlobalData.ChannelRuntimeService.DeleteChannelAsync(Items.Select(a => a.Id), AutoRestartThread, default);
await InvokeAsync(async () =>
{
await ToastService.Default();
@@ -386,7 +386,8 @@ finally
}
#endregion
[Parameter]
public bool AutoRestartThread { get; set; }
[Parameter]
public ChannelDeviceTreeItem SelectModel { get; set; }
[Inject]

View File

@@ -83,7 +83,7 @@ namespace ThingsGateway.Gateway.Razor
internal static async Task ShowCopy(Channel oneModel, Dictionary<Device, List<Variable>> deviceDict, string text, Func<Task> onsave, DialogService dialogService)
internal static async Task ShowCopy(Channel oneModel, Dictionary<Device, List<Variable>> deviceDict, string text, bool autoRestart, Func<Task> onsave, DialogService dialogService)
{
var op = new DialogOption()
{
@@ -100,7 +100,7 @@ namespace ThingsGateway.Gateway.Razor
{nameof(ChannelCopyComponent.OnSave), async (List<Channel> channels,Dictionary<Device,List<Variable>> devices) =>
{
await Task.Run(() =>GlobalData.ChannelRuntimeService.CopyAsync(channels,devices, default));
await Task.Run(() =>GlobalData.ChannelRuntimeService.CopyAsync(channels,devices,autoRestart, default));
if(onsave!=null)
await onsave();

View File

@@ -55,6 +55,9 @@ public partial class ChannelDeviceTree
await OnShowTypeChanged(showType);
}
[Parameter]
public bool AutoRestartThread { get; set; }
private static string GetClass(ChannelDeviceTreeItem item)
{
if (item.TryGetChannelRuntime(out var channelRuntime))
@@ -120,7 +123,7 @@ public partial class ChannelDeviceTree
{
{nameof(ChannelEditComponent.OnValidSubmit), async () =>
{
await Task.Run(() =>GlobalData.ChannelRuntimeService.SaveChannelAsync(oneModel,itemChangedType));
await Task.Run(() =>GlobalData.ChannelRuntimeService.SaveChannelAsync(oneModel,itemChangedType,AutoRestartThread));
////await Notify();
}},
{nameof(ChannelEditComponent.Model),oneModel },
@@ -172,7 +175,7 @@ public partial class ChannelDeviceTree
{nameof(ChannelCopyComponent.OnSave), async (List<Channel> channels,Dictionary<Device,List<Variable>> devices) =>
{
await Task.Run(() =>GlobalData.ChannelRuntimeService.CopyAsync(channels,devices, default));
await Task.Run(() =>GlobalData.ChannelRuntimeService.CopyAsync(channels,devices,AutoRestartThread, default));
//await Notify();
}},
@@ -247,7 +250,7 @@ public partial class ChannelDeviceTree
{nameof(ChannelEditComponent.OnValidSubmit), async () =>
{
Spinner.SetRun(true);
await Task.Run(() => GlobalData.ChannelRuntimeService.BatchEditAsync(changedModels, oldModel, oneModel));
await Task.Run(() => GlobalData.ChannelRuntimeService.BatchEditAsync(changedModels, oldModel, oneModel,AutoRestartThread));
//await Notify();
await InvokeAsync(() =>
@@ -298,7 +301,7 @@ public partial class ChannelDeviceTree
await Task.Run(async ()=>
{
var importData=await ChannelServiceHelpers.ImportAsync(data);
await GlobalData.ChannelRuntimeService.ImportChannelAsync(importData);
await GlobalData.ChannelRuntimeService.ImportChannelAsync(importData,AutoRestartThread);
})
;
}
@@ -424,7 +427,7 @@ finally
Spinner.SetRun(true);
await Task.Run(() => GlobalData.ChannelRuntimeService.DeleteChannelAsync(modelIds.Select(a => a.Id), default));
await Task.Run(() => GlobalData.ChannelRuntimeService.DeleteChannelAsync(modelIds.Select(a => a.Id), AutoRestartThread, default));
//await Notify();
await InvokeAsync(() =>
{
@@ -468,7 +471,7 @@ finally
Spinner.SetRun(true);
var key = await GlobalData.GetCurrentUserChannels().ConfigureAwait(false);
await Task.Run(() => GlobalData.ChannelRuntimeService.DeleteChannelAsync(key.Select(a => a.Id), default));
await Task.Run(() => GlobalData.ChannelRuntimeService.DeleteChannelAsync(key.Select(a => a.Id), AutoRestartThread, default));
//await Notify();
await InvokeAsync(() =>
{
@@ -601,7 +604,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
Spinner.SetRun(true);
});
await Task.Run(() => GlobalData.ChannelRuntimeService.ImportChannelAsync(value));
await Task.Run(() => GlobalData.ChannelRuntimeService.ImportChannelAsync(value, AutoRestartThread));
//await Notify();
await InvokeAsync(() =>
{
@@ -656,7 +659,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
{nameof(DeviceCopyComponent.OnSave), async (Dictionary<Device,List<Variable>> devices) =>
{
await Task.Run(() =>GlobalData.DeviceRuntimeService.CopyAsync(devices, default));
await Task.Run(() =>GlobalData.DeviceRuntimeService.CopyAsync(devices,AutoRestartThread, default));
//await Notify();
}},
@@ -709,10 +712,11 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
{
{nameof(DeviceEditComponent.OnValidSubmit), async () =>
{
await Task.Run(() =>GlobalData.DeviceRuntimeService.SaveDeviceAsync(oneModel,itemChangedType));
await Task.Run(() =>GlobalData.DeviceRuntimeService.SaveDeviceAsync(oneModel,itemChangedType, AutoRestartThread));
//await Notify();
}},
{nameof(DeviceEditComponent.Model),oneModel },
{nameof(DeviceEditComponent.AutoRestartThread),AutoRestartThread },
{nameof(DeviceEditComponent.ValidateEnable),true },
{nameof(DeviceEditComponent.BatchEditEnable),false },
});
@@ -794,7 +798,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
Spinner.SetRun(true);
});
await Task.Run(() =>GlobalData.DeviceRuntimeService.BatchEditAsync(changedModels,oldModel,oneModel));
await Task.Run(() =>GlobalData.DeviceRuntimeService.BatchEditAsync(changedModels,oldModel,oneModel,AutoRestartThread));
//await Notify();
await InvokeAsync(() =>
{
@@ -802,6 +806,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
});
}},
{nameof(DeviceEditComponent.Model),oneModel },
{nameof(DeviceEditComponent.AutoRestartThread),AutoRestartThread },
{nameof(DeviceEditComponent.ValidateEnable),true },
{nameof(DeviceEditComponent.BatchEditEnable),true },
});
@@ -837,7 +842,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
await Task.Run(async ()=>
{
var importData=await DeviceServiceHelpers.ImportAsync(data);
await GlobalData.DeviceRuntimeService.ImportDeviceAsync(importData);
await GlobalData.DeviceRuntimeService.ImportDeviceAsync(importData,AutoRestartThread);
})
;
}
@@ -969,7 +974,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
Spinner.SetRun(true);
await Task.Run(() => GlobalData.DeviceRuntimeService.DeleteDeviceAsync(modelIds.Select(a => a.Id), default));
await Task.Run(() => GlobalData.DeviceRuntimeService.DeleteDeviceAsync(modelIds.Select(a => a.Id), AutoRestartThread, default));
//await Notify();
await InvokeAsync(() =>
{
@@ -1016,7 +1021,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
var data = await GlobalData.GetCurrentUserDevices().ConfigureAwait(false);
await Task.Run(() => GlobalData.DeviceRuntimeService.DeleteDeviceAsync(data.Select(a => a.Id), default));
await Task.Run(() => GlobalData.DeviceRuntimeService.DeleteDeviceAsync(data.Select(a => a.Id), AutoRestartThread, default));
//await Notify();
await InvokeAsync(() =>
{
@@ -1150,7 +1155,7 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
});
await Task.Run(() => GlobalData.DeviceRuntimeService.ImportDeviceAsync(value));
await Task.Run(() => GlobalData.DeviceRuntimeService.ImportDeviceAsync(value, AutoRestartThread));
//await Notify();
await InvokeAsync(() =>
{

View File

@@ -28,6 +28,8 @@ public partial class DeviceEditComponent
[EditorRequired]
public Device Model { get; set; }
[Parameter]
public bool AutoRestartThread { get; set; }
[Parameter]
public Func<Task> OnValidSubmit { get; set; }
@@ -86,7 +88,7 @@ public partial class DeviceEditComponent
{
{nameof(ChannelEditComponent.OnValidSubmit), async () =>
{
await Task.Run(() =>GlobalData.ChannelRuntimeService.SaveChannelAsync(oneModel,ItemChangedType.Add));
await Task.Run(() =>GlobalData.ChannelRuntimeService.SaveChannelAsync(oneModel,ItemChangedType.Add,AutoRestartThread));
OnParametersSet();
}},
{nameof(ChannelEditComponent.Model),oneModel },

View File

@@ -66,7 +66,7 @@
</TableColumns>
<EditTemplate Context="context">
<DeviceEditComponent Model=@(context) ValidateEnable=false BatchEditEnable=false></DeviceEditComponent>
<DeviceEditComponent Model=@(context) ValidateEnable=false BatchEditEnable=false AutoRestartThread=AutoRestartThread></DeviceEditComponent>
</EditTemplate>

View File

@@ -133,7 +133,7 @@ public partial class DeviceTable : IDisposable
{nameof(DeviceCopyComponent.OnSave), async (Dictionary<Device,List<Variable>> devices) =>
{
await Task.Run(() =>GlobalData.DeviceRuntimeService.CopyAsync(devices, default));
await Task.Run(() =>GlobalData.DeviceRuntimeService.CopyAsync(devices,AutoRestartThread, default));
await InvokeAsync(table.QueryAsync);
}},
@@ -173,7 +173,7 @@ public partial class DeviceTable : IDisposable
{
{nameof(DeviceEditComponent.OnValidSubmit), async () =>
{
await Task.Run(() => GlobalData.DeviceRuntimeService.BatchEditAsync(changedModels, oldModel, oneModel));
await Task.Run(() => GlobalData.DeviceRuntimeService.BatchEditAsync(changedModels, oldModel, oneModel,AutoRestartThread));
await InvokeAsync(table.QueryAsync);
@@ -196,7 +196,7 @@ public partial class DeviceTable : IDisposable
{
return await Task.Run(async () =>
{
return await GlobalData.DeviceRuntimeService.DeleteDeviceAsync(devices.Select(a => a.Id), default);
return await GlobalData.DeviceRuntimeService.DeleteDeviceAsync(devices.Select(a => a.Id), AutoRestartThread, default);
});
}
catch (Exception ex)
@@ -215,7 +215,7 @@ public partial class DeviceTable : IDisposable
{
device.DevicePropertys = PluginServiceUtil.SetDict(device.ModelValueValidateForm.Value);
device = device.AdaptDevice();
return await Task.Run(() => GlobalData.DeviceRuntimeService.SaveDeviceAsync(device, itemChangedType));
return await Task.Run(() => GlobalData.DeviceRuntimeService.SaveDeviceAsync(device, itemChangedType, AutoRestartThread));
}
catch (Exception ex)
{
@@ -305,7 +305,7 @@ public partial class DeviceTable : IDisposable
await Task.Run(async ()=>
{
var importData=await DeviceServiceHelpers.ImportAsync(data);
await GlobalData.DeviceRuntimeService.ImportDeviceAsync(importData);
await GlobalData.DeviceRuntimeService.ImportDeviceAsync(importData,AutoRestartThread);
})
;
}
@@ -347,7 +347,7 @@ finally
};
Func<IBrowserFile, Task<Dictionary<string, ImportPreviewOutputBase>>> preview = (a => GlobalData.DeviceRuntimeService.PreviewAsync(a));
Func<Dictionary<string, ImportPreviewOutputBase>, Task> import = (value => GlobalData.DeviceRuntimeService.ImportDeviceAsync(value));
Func<Dictionary<string, ImportPreviewOutputBase>, Task> import = (value => GlobalData.DeviceRuntimeService.ImportDeviceAsync(value, AutoRestartThread));
op.Component = BootstrapDynamicComponent.CreateComponent<ImportExcel>(new Dictionary<string, object?>
{
{nameof(ImportExcel.Import),import },
@@ -368,7 +368,7 @@ finally
await Task.Run(async () =>
{
await GlobalData.DeviceRuntimeService.DeleteDeviceAsync(Items.Select(a => a.Id), default);
await GlobalData.DeviceRuntimeService.DeleteDeviceAsync(Items.Select(a => a.Id), AutoRestartThread, default);
await InvokeAsync(async () =>
{
await ToastService.Default();
@@ -387,7 +387,8 @@ finally
}
#endregion
[Parameter]
public bool AutoRestartThread { get; set; }
[Parameter]
public ChannelDeviceTreeItem SelectModel { get; set; }
[Inject]

View File

@@ -22,10 +22,10 @@ else if (ShowType == ShowTypeEnum.LogInfo)
}
else if (ShowType == ShowTypeEnum.ChannelTable)
{
<ChannelTable SelectModel="SelectModel" Items="ChannelRuntimes"/>
<ChannelTable SelectModel="SelectModel" Items="ChannelRuntimes" AutoRestartThread=AutoRestartThread />
}
else if (ShowType == ShowTypeEnum.DeviceTable)
{
<DeviceTable SelectModel="SelectModel" Items="DeviceRuntimes"/>
<DeviceTable SelectModel="SelectModel" Items="DeviceRuntimes" AutoRestartThread=AutoRestartThread />
}

View File

@@ -15,7 +15,7 @@
<Card IsShadow=true class="h-100 me-1" Color="Color.Primary">
<BodyTemplate>
<ChannelDeviceTree @bind-ShowType=ShowType
<ChannelDeviceTree @bind-ShowType=ShowType AutoRestartThread="AutoRestartThread"
ChannelDeviceChanged="TreeChangedAsync" Value="SelectModel"></ChannelDeviceTree>
</BodyTemplate>
</Card>

View File

@@ -214,10 +214,11 @@ public partial class VariableEditComponent
{
{nameof(DeviceEditComponent.OnValidSubmit), async () =>
{
await Task.Run(() =>GlobalData.DeviceRuntimeService.SaveDeviceAsync(oneModel,ItemChangedType.Add));
await Task.Run(() =>GlobalData.DeviceRuntimeService.SaveDeviceAsync(oneModel,ItemChangedType.Add,AutoRestartThread));
OnParametersSet();
}},
{nameof(DeviceEditComponent.Model),oneModel },
{nameof(DeviceEditComponent.AutoRestartThread),AutoRestartThread },
{nameof(DeviceEditComponent.ValidateEnable),true },
{nameof(DeviceEditComponent.BatchEditEnable),false },
});

View File

@@ -377,7 +377,7 @@ public partial class SiemensS7Master : DeviceBase
#endregion
#region
private WaitLock ChannelStartedWaitLock = new();
private WaitLock ChannelStartedWaitLock = new(nameof(SiemensS7Master));
private SiemensTypeEnum siemensS7Type;
/// <inheritdoc/>

View File

@@ -47,7 +47,7 @@ public partial class MqttClient : BusinessBaseWithCacheIntervalScriptAll
private MqttClientSubscribeOptions _mqttSubscribeOptions;
private WaitLock ConnectLock = new();
private WaitLock ConnectLock = new(nameof(MqttClient));
protected override void AlarmChange(AlarmVariable alarmVariable)
{

View File

@@ -35,7 +35,7 @@ public partial class MqttCollect : CollectBase
private MqttClientSubscribeOptions _mqttSubscribeOptions;
private WaitLock ConnectLock = new();
private WaitLock ConnectLock = new(nameof(MqttCollect));
#region mqtt方法

View File

@@ -234,8 +234,8 @@ public partial class OpcDaImportVariable
await ToastService.Warning(OpcDaPropertyLocalizer["NoVariablesAvailable"], OpcDaPropertyLocalizer["NoVariablesAvailable"]);
return;
}
await App.RootServices.GetRequiredService<IChannelRuntimeService>().SaveChannelAsync(data.Item1, ItemChangedType.Add);
await App.RootServices.GetRequiredService<IDeviceRuntimeService>().SaveDeviceAsync(data.Item2, ItemChangedType.Add);
await App.RootServices.GetRequiredService<IChannelRuntimeService>().SaveChannelAsync(data.Item1, ItemChangedType.Add, true);
await App.RootServices.GetRequiredService<IDeviceRuntimeService>().SaveDeviceAsync(data.Item2, ItemChangedType.Add, true);
await App.RootServices.GetRequiredService<IVariableRuntimeService>().BatchSaveVariableAsync(data.Item3, ItemChangedType.Add, true, default);
await ToastService.Default();
}

View File

@@ -263,8 +263,8 @@ public partial class OpcUaImportVariable
await ToastService.Warning(OpcUaPropertyLocalizer["NoVariablesAvailable"], OpcUaPropertyLocalizer["NoVariablesAvailable"]);
return;
}
await App.RootServices.GetRequiredService<IChannelRuntimeService>().SaveChannelAsync(data.Item1, ItemChangedType.Add);
await App.RootServices.GetRequiredService<IDeviceRuntimeService>().SaveDeviceAsync(data.Item2, ItemChangedType.Add);
await App.RootServices.GetRequiredService<IChannelRuntimeService>().SaveChannelAsync(data.Item1, ItemChangedType.Add, true);
await App.RootServices.GetRequiredService<IDeviceRuntimeService>().SaveDeviceAsync(data.Item2, ItemChangedType.Add, true);
await App.RootServices.GetRequiredService<IVariableRuntimeService>().BatchSaveVariableAsync(data.Item3.ToList(), ItemChangedType.Add, true, default);
await ToastService.Default();
}

View File

@@ -23,7 +23,7 @@
<title>ThingsGateway</title>
@{
#if !NET8_0
#if !NET8_0
}
<link rel="stylesheet" href=@(Assets[$"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css"]) />