mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-20 10:50:48 +08:00
@@ -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.41</PluginVersion>
|
||||
<ProPluginVersion>10.9.41</ProPluginVersion>
|
||||
<DefaultVersion>10.9.41</DefaultVersion>
|
||||
<AuthenticationVersion>2.9.18</AuthenticationVersion>
|
||||
<SourceGeneratorVersion>10.9.18</SourceGeneratorVersion>
|
||||
<NET8Version>8.0.18</NET8Version>
|
||||
<NET9Version>9.0.7</NET9Version>
|
||||
<SatelliteResourceLanguages>zh-Hans;en-US</SatelliteResourceLanguages>
|
||||
|
@@ -350,9 +350,6 @@ public abstract class DeviceBase : DisposableObject, IDevice
|
||||
if (SendDelayTime != 0)
|
||||
await Task.Delay(SendDelayTime, token).ConfigureAwait(false);
|
||||
|
||||
if (token.IsCancellationRequested)
|
||||
return new OperResult(new OperationCanceledException());
|
||||
|
||||
if (channel is IDtuUdpSessionChannel udpSession)
|
||||
{
|
||||
await udpSession.SendAsync(endPoint, sendMessage).ConfigureAwait(false);
|
||||
@@ -560,9 +557,6 @@ public abstract class DeviceBase : DisposableObject, IDevice
|
||||
if (clientChannel.ReadOnlyDataHandlingAdapter != null)
|
||||
clientChannel.ReadOnlyDataHandlingAdapter.Logger = Logger;
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return new MessageBase(new OperationCanceledException());
|
||||
|
||||
waitData.SetCancellationToken(cancellationToken);
|
||||
|
||||
Channel.ChannelReceivedWaitDict.TryAdd(sign, ChannelReceived);
|
||||
@@ -572,14 +566,6 @@ public abstract class DeviceBase : DisposableObject, IDevice
|
||||
|
||||
await waitData.WaitAsync(timeout).ConfigureAwait(false);
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (!this.DisposedValue)
|
||||
{
|
||||
await Task.Delay(timeout, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
var result = waitData.Check();
|
||||
if (result.IsSuccess)
|
||||
{
|
||||
|
@@ -16,18 +16,17 @@ public class AsyncReadWriteLock
|
||||
{
|
||||
private AsyncAutoResetEvent _readerLock = new AsyncAutoResetEvent(false); // 控制读计数
|
||||
private long _writerCount = 0; // 当前活跃的写线程数
|
||||
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
/// <summary>
|
||||
/// 获取读锁,支持多个线程并发读取,但写入时会阻止所有读取。
|
||||
/// </summary>
|
||||
public async Task<CancellationToken> ReaderLockAsync(CancellationToken cancellationToken)
|
||||
public async Task ReaderLockAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (Interlocked.Read(ref _writerCount) > 0)
|
||||
{
|
||||
// 第一个读者需要获取写入锁,防止写操作
|
||||
await _readerLock.WaitOneAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
return _cancellationTokenSource.Token;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -35,14 +34,7 @@ public class AsyncReadWriteLock
|
||||
/// </summary>
|
||||
public IDisposable WriterLock()
|
||||
{
|
||||
if (Interlocked.Increment(ref _writerCount) == 1)
|
||||
{
|
||||
var cancellationTokenSource = _cancellationTokenSource;
|
||||
_cancellationTokenSource = new();
|
||||
cancellationTokenSource.Cancel();//取消读取
|
||||
cancellationTokenSource.SafeDispose();
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref _writerCount);
|
||||
return new Writer(this);
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
return GlobalData.DeviceRuntimeService.BatchSaveDeviceAsync(devices.AdaptListDevice(), type);
|
||||
return GlobalData.DeviceRuntimeService.BatchSaveDeviceAsync(devices.AdaptListDevice(), type, restart);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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>
|
||||
|
@@ -344,25 +344,18 @@ public abstract class CollectBase : DriverBase, IRpcDriver
|
||||
{
|
||||
if (state is not VariableSourceRead variableSourceRead) return;
|
||||
|
||||
if (Pause) return;
|
||||
if (cancellationToken.IsCancellationRequested) return;
|
||||
if (Pause)
|
||||
return;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
var readErrorCount = 0;
|
||||
|
||||
var readToken = await ReadWriteLock.ReaderLockAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (readToken.IsCancellationRequested)
|
||||
{
|
||||
await ReadVariableSource(state, cancellationToken).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
using var allTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, readToken);
|
||||
var allToken = allTokenSource.Token;
|
||||
await ReadWriteLock.ReaderLockAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
//if (LogMessage?.LogLevel <= TouchSocket.Core.LogLevel.Trace)
|
||||
// LogMessage?.Trace(string.Format("{0} - Collecting [{1} - {2}]", DeviceName, variableSourceRead?.RegisterAddress, variableSourceRead?.Length));
|
||||
var readResult = await ReadSourceAsync(variableSourceRead, allToken).ConfigureAwait(false);
|
||||
var readResult = await ReadSourceAsync(variableSourceRead, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// 读取失败时重试一定次数
|
||||
while (!readResult.IsSuccess && readErrorCount < CollectProperties.RetryCount)
|
||||
@@ -372,12 +365,6 @@ public abstract class CollectBase : DriverBase, IRpcDriver
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
if (readToken.IsCancellationRequested)
|
||||
{
|
||||
await ReadVariableSource(state, cancellationToken).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
readErrorCount++;
|
||||
if (LogMessage?.LogLevel <= TouchSocket.Core.LogLevel.Trace)
|
||||
LogMessage?.Trace(string.Format("{0} - Collection [{1} - {2}] failed - {3}", DeviceName, variableSourceRead?.RegisterAddress, variableSourceRead?.Length, readResult.ErrorMessage));
|
||||
@@ -400,12 +387,6 @@ public abstract class CollectBase : DriverBase, IRpcDriver
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
if (readToken.IsCancellationRequested)
|
||||
{
|
||||
await ReadVariableSource(state, cancellationToken).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 读取失败时记录日志并增加失败计数器,更新错误信息并清除变量状态
|
||||
if (variableSourceRead.LastErrorMessage != readResult.ErrorMessage)
|
||||
{
|
||||
|
@@ -25,12 +25,7 @@ public class RpcLog : PrimaryIdEntity
|
||||
[SugarColumn(ColumnDescription = "日志时间", IsNullable = false)]
|
||||
[AutoGenerateColumn(Visible = true, DefaultSort = true, Sortable = true, DefaultSortOrder = SortOrder.Desc)]
|
||||
public DateTime LogTime { get; set; }
|
||||
/// <summary>
|
||||
/// 执行时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "执行时间", IsNullable = true)]
|
||||
[AutoGenerateColumn(Visible = true, DefaultSort = true, Sortable = true, DefaultSortOrder = SortOrder.Desc)]
|
||||
public int ExecutionTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 操作源
|
||||
///</summary>
|
||||
|
@@ -404,7 +404,6 @@
|
||||
"OperateMethod": "RPCMethod",
|
||||
"OperateObject": "OperationObject",
|
||||
"OperateSource": "OperationSource",
|
||||
"ExecutionTime": "ExecutionTime",
|
||||
"ParamJson": "RequestParameters",
|
||||
"ResultJson": "ReturnResults"
|
||||
},
|
||||
|
@@ -405,7 +405,6 @@
|
||||
"OperateMethod": "RPC方法",
|
||||
"OperateObject": "操作对象",
|
||||
"OperateSource": "操作源",
|
||||
"ExecutionTime": "执行时间",
|
||||
"ParamJson": "请求参数",
|
||||
"ResultJson": "返回结果"
|
||||
},
|
||||
|
@@ -26,7 +26,7 @@ public class ChannelRuntimeService : IChannelRuntimeService
|
||||
}
|
||||
private WaitLock WaitLock { get; set; } = new WaitLock();
|
||||
|
||||
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 = true)
|
||||
{
|
||||
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 = true)
|
||||
{
|
||||
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 = true)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
@@ -30,7 +30,7 @@ public class DeviceRuntimeService : IDeviceRuntimeService
|
||||
private WaitLock WaitLock { get; set; } = new WaitLock();
|
||||
|
||||
|
||||
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 = true)
|
||||
{
|
||||
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 = true)
|
||||
{
|
||||
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 = true)
|
||||
{
|
||||
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);
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -428,22 +428,22 @@ internal sealed class DeviceThreadManage : IAsyncDisposable, IDeviceThreadManage
|
||||
|
||||
|
||||
if (DriverTasks.TryRemove(deviceId, out var task))
|
||||
{
|
||||
task.Stop();
|
||||
}
|
||||
{
|
||||
task.Stop();
|
||||
}
|
||||
|
||||
// 取消驱动程序的操作
|
||||
if (CancellationTokenSources.TryRemove(deviceId, out var token))
|
||||
{
|
||||
if (token != null)
|
||||
{
|
||||
token.Cancel();
|
||||
token.Dispose();
|
||||
}
|
||||
}
|
||||
// 取消驱动程序的操作
|
||||
if (CancellationTokenSources.TryRemove(deviceId, out var token))
|
||||
{
|
||||
if (token != null)
|
||||
{
|
||||
token.Cancel();
|
||||
token.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
await Task.Delay(100).ConfigureAwait(false);
|
||||
|
@@ -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");
|
||||
|
||||
|
@@ -130,10 +130,9 @@ internal sealed class RpcService : IRpcService
|
||||
{
|
||||
try
|
||||
{
|
||||
var start = DateTime.Now;
|
||||
// 调用设备的写入方法
|
||||
var result = await driverData.Key.InVokeWriteAsync(driverData.Value, cancellationToken).ConfigureAwait(false);
|
||||
var end = DateTime.Now;
|
||||
|
||||
// 写入日志
|
||||
foreach (var resultItem in result)
|
||||
{
|
||||
@@ -150,8 +149,7 @@ internal sealed class RpcService : IRpcService
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
{
|
||||
LogTime = start,
|
||||
ExecutionTime = (int)(end - start).TotalMilliseconds,
|
||||
LogTime = DateTime.Now,
|
||||
OperateMessage = variableResult.Value.IsSuccess ? null : variableResult.Value.ToString(),
|
||||
IsSuccess = variableResult.Value.IsSuccess,
|
||||
OperateMethod = AppResource.WriteVariable,
|
||||
@@ -192,12 +190,10 @@ internal sealed class RpcService : IRpcService
|
||||
{
|
||||
try
|
||||
{
|
||||
var start = DateTime.Now;
|
||||
// 调用设备的写入方法
|
||||
var result = await driverData.Key.InvokeMethodAsync(driverData.Value, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
Dictionary<string, string> operateMethods = driverData.Value.Select(a => a.Key).ToDictionary(a => a.Name, a => a.OtherMethod!);
|
||||
var end = DateTime.Now;
|
||||
|
||||
// 写入日志
|
||||
foreach (var resultItem in result)
|
||||
@@ -214,8 +210,7 @@ internal sealed class RpcService : IRpcService
|
||||
_logQueues.Enqueue(
|
||||
new RpcLog()
|
||||
{
|
||||
LogTime = start,
|
||||
ExecutionTime = (int)(end - start).TotalMilliseconds,
|
||||
LogTime = DateTime.Now,
|
||||
OperateMessage = variableResult.Value.IsSuccess ? null : variableResult.Value.ToString(),
|
||||
IsSuccess = variableResult.Value.IsSuccess,
|
||||
OperateMethod = operateMethods[variableResult.Key],
|
||||
|
@@ -184,7 +184,7 @@
|
||||
"Reload": "重载"
|
||||
},
|
||||
"ThingsGateway.Gateway.Razor.QuickActions": {
|
||||
"AutoRestartThread": "变量修改立即生效",
|
||||
"AutoRestartThread": "自动重启线程",
|
||||
"HeaderText": "快捷操作",
|
||||
"ReloadPluginConfirmText": "确定重载插件?",
|
||||
"ReloadServiceConfirmText": "确定重启运行时?",
|
||||
|
@@ -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]
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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(() =>
|
||||
{
|
||||
|
@@ -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 },
|
||||
|
@@ -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>
|
||||
|
||||
|
||||
|
@@ -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]
|
||||
|
@@ -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 />
|
||||
}
|
@@ -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>
|
||||
|
@@ -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 },
|
||||
});
|
||||
|
@@ -148,16 +148,17 @@ public class OpcDaMaster : CollectBase
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override ValueTask<OperResult<byte[]>> ReadSourceAsync(VariableSourceRead deviceVariableSourceRead, CancellationToken cancellationToken)
|
||||
protected override async ValueTask<OperResult<byte[]>> ReadSourceAsync(VariableSourceRead deviceVariableSourceRead, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ReadWriteLock.ReaderLockAsync(cancellationToken).ConfigureAwait(false);
|
||||
_plc.ReadItemsWithGroup(deviceVariableSourceRead.RegisterAddress);
|
||||
return ValueTask.FromResult(OperResult.CreateSuccessResult(Array.Empty<byte>()));
|
||||
return OperResult.CreateSuccessResult(Array.Empty<byte>());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ValueTask.FromResult(new OperResult<byte[]>($"ReadSourceAsync Error:{Environment.NewLine}{ex}"));
|
||||
return new OperResult<byte[]>($"ReadSourceAsync Error:{Environment.NewLine}{ex}");
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -247,6 +247,7 @@ public class OpcUaMaster : CollectBase
|
||||
var addresss = deviceVariableSourceRead.VariableRuntimes.Where(a => !a.RegisterAddress.IsNullOrEmpty()).Select(a => a.RegisterAddress!).ToArray();
|
||||
try
|
||||
{
|
||||
await ReadWriteLock.ReaderLockAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var result = await _plc.ReadJTokenValueAsync(addresss, cancellationToken).ConfigureAwait(false);
|
||||
foreach (var data in result)
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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"]) />
|
||||
|
Reference in New Issue
Block a user