build: 10.9.26

fix: opcuaserver添加变量属性出现错误,已回退
refactor: 网关监控树节点保持展开状态
refactor: cache插件类日志输出
This commit is contained in:
Diego
2025-07-08 14:33:27 +08:00
parent 34120da008
commit fe79128d90
7 changed files with 279 additions and 228 deletions

View File

@@ -105,6 +105,7 @@ public static class DictionaryExtensions
return list;
}
/// <summary>
/// 批量出队
/// </summary>
@@ -131,6 +132,7 @@ public static class DictionaryExtensions
}
}
/// <summary>
/// 批量出队
/// </summary>
@@ -157,7 +159,6 @@ public static class DictionaryExtensions
}
}
/// <summary>
/// 批量出队
/// </summary>
@@ -187,6 +188,7 @@ public static class DictionaryExtensions
}
return dict;
}
/// <summary>
/// 批量出队
/// </summary>
@@ -214,4 +216,35 @@ public static class DictionaryExtensions
}
}
/// <summary>
/// 批量出队
/// </summary>
public static List<TKEY> ToListWithDequeue<TKEY>(this ConcurrentHashSet<TKEY> values, int maxCount = 0)
{
List<TKEY> result = new();
if (values.IsEmpty) return result;
if (maxCount <= 0)
{
maxCount = values.Count;
}
else
{
maxCount = Math.Min(maxCount, values.Count);
}
var keys = values.Keys;
foreach (var key in keys)
{
if (maxCount-- <= 0) break;
if (values.TryRemove(key))
{
result.Add(key);
}
}
return result;
}
}

View File

@@ -1,9 +1,9 @@
<Project>
<PropertyGroup>
<PluginVersion>10.9.25</PluginVersion>
<ProPluginVersion>10.9.25</ProPluginVersion>
<DefaultVersion>10.9.25</DefaultVersion>
<PluginVersion>10.9.26</PluginVersion>
<ProPluginVersion>10.9.26</ProPluginVersion>
<DefaultVersion>10.9.26</DefaultVersion>
<AuthenticationVersion>2.9.13</AuthenticationVersion>
<SourceGeneratorVersion>10.9.13</SourceGeneratorVersion>
<NET8Version>8.0.17</NET8Version>

View File

@@ -173,7 +173,7 @@ public abstract class BusinessBaseWithCache : BusinessBase
{
if (_memoryAlarmModelQueue.Count > _businessPropertyWithCache.QueueMaxCount)
{
LogMessage?.LogWarning($"{typeof(AlarmVariable).Name} Queue exceeds limit, clear old data. If it doesn't work as expected, increase [QueueMaxCount] or Enable cache");
LogMessage?.LogWarning($"{typeof(AlarmVariable).Name} Queue exceeds limit, clear old data. If it doesn't work as expected, increase {_businessPropertyWithCache.QueueMaxCount} or Enable cache");
_memoryAlarmModelQueue.Clear();
_memoryAlarmModelQueue.Enqueue(data);
return;
@@ -405,7 +405,7 @@ public abstract class BusinessBaseWithCache : BusinessBase
{
if (_memoryDevModelQueue.Count > _businessPropertyWithCache.QueueMaxCount)
{
LogMessage?.LogWarning($"{typeof(DeviceBasicData).Name} Queue exceeds limit, clear old data. If it doesn't work as expected, increase [QueueMaxCount] or Enable cache");
LogMessage?.LogWarning($"{typeof(DeviceBasicData).Name} Queue exceeds limit, clear old data. If it doesn't work as expected, increase {_businessPropertyWithCache.QueueMaxCount} or Enable cache");
_memoryDevModelQueue.Clear();
_memoryDevModelQueue.Enqueue(data);
return;
@@ -685,7 +685,7 @@ public abstract class BusinessBaseWithCache : BusinessBase
{
if (_memoryVarModelQueue.Count > _businessPropertyWithCache.QueueMaxCount)
{
LogMessage?.LogWarning($"{typeof(VariableBasicData).Name} Queue exceeds limit, clear old data. If it doesn't work as expected, increase [QueueMaxCount] or Enable cache");
LogMessage?.LogWarning($"{typeof(VariableBasicData).Name} Queue exceeds limit, clear old data. If it doesn't work as expected, increase {_businessPropertyWithCache.QueueMaxCount} or Enable cache");
_memoryVarModelQueue.Clear();
_memoryVarModelQueue.Enqueue(data);
return;

View File

@@ -4,50 +4,66 @@ namespace ThingsGateway.Gateway.Razor
{
public static class TreeViewItemMapper
{
public static global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>> AdaptListTreeViewItemChannelDeviceTreeItem(this global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>> src, global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> parent = null)
public static global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>> AdaptListTreeViewItemChannelDeviceTreeItem(this global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>> src)
{
var target = new global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>>(src.Count);
foreach (var item in src)
NormalizeItems(src);
return src.ToList();
}
static void NormalizeItems<T>(List<TreeViewItem<T>> nodes)
{
foreach (var node in nodes)
{
target.Add(MapToTreeViewItemOfChannelDeviceTreeItem(item, parent));
if (node.Items.Count > 0)
{
node.Items = node.Items.ToList();
NormalizeItems(node.Items);
}
}
return target;
}
//public static global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>> AdaptListTreeViewItemChannelDeviceTreeItem(this global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>> src, global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> parent = null)
//{
// var target = new global::System.Collections.Generic.List<global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>>(src.Count);
// foreach (var item in src)
// {
// target.Add(MapToTreeViewItemOfChannelDeviceTreeItem(item, parent));
// }
// return target;
//}
private static global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> MapToTreeViewItemOfChannelDeviceTreeItem(global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> source, global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> parent)
{
var target = new global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>(source.Value);
target.CheckedState = source.CheckedState;
target.Items = AdaptListTreeViewItemChannelDeviceTreeItem(source.Items.ToList(), target);
if (source.Parent != null && parent != null)
{
target.Parent = parent;
}
else
{
target.Parent = null;
}
target.Text = source.Text;
target.Icon = source.Icon;
target.ExpandIcon = source.ExpandIcon;
target.CssClass = source.CssClass;
target.IsDisabled = source.IsDisabled;
target.IsActive = source.IsActive;
target.Template = source.Template;
if (source.Value != null)
{
target.Value = source.Value;
}
else
{
target.Value = null;
}
target.IsExpand = source.IsExpand;
target.HasChildren = source.HasChildren;
return target;
}
//private static global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> MapToTreeViewItemOfChannelDeviceTreeItem(global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> source, global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem> parent)
//{
// var target = new global::BootstrapBlazor.Components.TreeViewItem<global::ThingsGateway.Gateway.Razor.ChannelDeviceTreeItem>(source.Value);
// target.CheckedState = source.CheckedState;
// target.Items = AdaptListTreeViewItemChannelDeviceTreeItem(source.Items.ToList(), target);
// if (source.Parent != null && parent != null)
// {
// target.Parent = parent;
// }
// else
// {
// target.Parent = null;
// }
// target.Text = source.Text;
// target.Icon = source.Icon;
// target.ExpandIcon = source.ExpandIcon;
// target.CssClass = source.CssClass;
// target.IsDisabled = source.IsDisabled;
// target.IsActive = source.IsActive;
// target.Template = source.Template;
// if (source.Value != null)
// {
// target.Value = source.Value;
// }
// else
// {
// target.Value = null;
// }
// target.IsExpand = source.IsExpand;
// target.HasChildren = source.HasChildren;
// return target;
//}
}

View File

@@ -1240,19 +1240,19 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
UnknownTreeViewItem = new TreeViewItem<ChannelDeviceTreeItem>(UnknownItem)
{
Text = GatewayLocalizer["Unknown"],
IsActive = Value == UnknownItem,
IsActive = false,
IsExpand = true,
};
ZItem = new List<TreeViewItem<ChannelDeviceTreeItem>>() {new TreeViewItem<ChannelDeviceTreeItem>(CollectItem)
{
Text = GatewayLocalizer["Collect"],
IsActive = Value == CollectItem,
IsActive = false,
IsExpand = true,
},
new TreeViewItem<ChannelDeviceTreeItem>(BusinessItem)
{
Text = GatewayLocalizer["Business"],
IsActive = Value == BusinessItem,
IsActive = false,
IsExpand = true,
}};
@@ -1533,13 +1533,5 @@ EventCallback.Factory.Create<MouseEventArgs>(this, async e =>
}
return Task.CompletedTask;
}
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
}
private void OnUpdateCallbackAsync()
{
throw new NotImplementedException();
}
}

View File

@@ -395,78 +395,78 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
};
// 添加自定义属性
{
var property = new PropertyState<string>(folder)
{
NodeId = new NodeId($"{deviceRuntime.Name}.PluginName", NamespaceIndex),
BrowseName = new QualifiedName("PluginName", NamespaceIndex),
DisplayName = "PluginName",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = deviceRuntime.PluginName ?? string.Empty
};
AddProperty(folder, property);
}
{
var property = new PropertyState<string>(folder)
{
NodeId = new NodeId($"{deviceRuntime.Name}.Remark1", NamespaceIndex),
BrowseName = new QualifiedName("Remark1", NamespaceIndex),
DisplayName = "Remark1",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = deviceRuntime.Remark1 ?? string.Empty
};
AddProperty(folder, property);
}
{
var property = new PropertyState<string>(folder)
{
NodeId = new NodeId($"{deviceRuntime.Name}.Remark2", NamespaceIndex),
BrowseName = new QualifiedName("Remark2", NamespaceIndex),
DisplayName = "Remark2",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = deviceRuntime.Remark2 ?? string.Empty
};
AddProperty(folder, property);
}
{
var property = new PropertyState<string>(folder)
{
NodeId = new NodeId($"{deviceRuntime.Name}.Remark3", NamespaceIndex),
BrowseName = new QualifiedName("Remark3", NamespaceIndex),
DisplayName = "Remark3",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = deviceRuntime.Remark3 ?? string.Empty
};
AddProperty(folder, property);
}
{
var property = new PropertyState<string>(folder)
{
NodeId = new NodeId($"{deviceRuntime.Name}.Remark4", NamespaceIndex),
BrowseName = new QualifiedName("Remark4", NamespaceIndex),
DisplayName = "Remark4",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = deviceRuntime.Remark4 ?? string.Empty
};
AddProperty(folder, property);
}
{
var property = new PropertyState<string>(folder)
{
NodeId = new NodeId($"{deviceRuntime.Name}.Remark5", NamespaceIndex),
BrowseName = new QualifiedName("Remark5", NamespaceIndex),
DisplayName = "Remark5",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = deviceRuntime.Remark5 ?? string.Empty
};
AddProperty(folder, property);
}
//{
// var property = new PropertyState<string>(folder)
// {
// NodeId = new NodeId($"{deviceRuntime.Name}.PluginName", NamespaceIndex),
// BrowseName = new QualifiedName("PluginName", NamespaceIndex),
// DisplayName = "PluginName",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = deviceRuntime.PluginName ?? string.Empty
// };
// AddProperty(folder, property);
//}
//{
// var property = new PropertyState<string>(folder)
// {
// NodeId = new NodeId($"{deviceRuntime.Name}.Remark1", NamespaceIndex),
// BrowseName = new QualifiedName("Remark1", NamespaceIndex),
// DisplayName = "Remark1",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = deviceRuntime.Remark1 ?? string.Empty
// };
// AddProperty(folder, property);
//}
//{
// var property = new PropertyState<string>(folder)
// {
// NodeId = new NodeId($"{deviceRuntime.Name}.Remark2", NamespaceIndex),
// BrowseName = new QualifiedName("Remark2", NamespaceIndex),
// DisplayName = "Remark2",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = deviceRuntime.Remark2 ?? string.Empty
// };
// AddProperty(folder, property);
//}
//{
// var property = new PropertyState<string>(folder)
// {
// NodeId = new NodeId($"{deviceRuntime.Name}.Remark3", NamespaceIndex),
// BrowseName = new QualifiedName("Remark3", NamespaceIndex),
// DisplayName = "Remark3",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = deviceRuntime.Remark3 ?? string.Empty
// };
// AddProperty(folder, property);
//}
//{
// var property = new PropertyState<string>(folder)
// {
// NodeId = new NodeId($"{deviceRuntime.Name}.Remark4", NamespaceIndex),
// BrowseName = new QualifiedName("Remark4", NamespaceIndex),
// DisplayName = "Remark4",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = deviceRuntime.Remark4 ?? string.Empty
// };
// AddProperty(folder, property);
//}
//{
// var property = new PropertyState<string>(folder)
// {
// NodeId = new NodeId($"{deviceRuntime.Name}.Remark5", NamespaceIndex),
// BrowseName = new QualifiedName("Remark5", NamespaceIndex),
// DisplayName = "Remark5",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = deviceRuntime.Remark5 ?? string.Empty
// };
// AddProperty(folder, property);
//}
parent?.AddChild(folder);
@@ -507,101 +507,101 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
variable.StatusCode = code;
variable.Timestamp = variableRuntime.CollectTime;
variable.OnWriteValue = OnWriteDataValue;
parent?.AddChild(variable);
// 添加自定义属性
{
var property = new PropertyState<string>(variable)
{
NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Unit", NamespaceIndex),
BrowseName = new QualifiedName("Unit", NamespaceIndex),
DisplayName = "Unit",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = variableRuntime.Unit ?? string.Empty
};
AddProperty(variable, property);
//// 添加自定义属性
//{
// var property = new PropertyState<string>(variable)
// {
// NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Unit", NamespaceIndex),
// BrowseName = new QualifiedName("Unit", NamespaceIndex),
// DisplayName = "Unit",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = variableRuntime.Unit ?? string.Empty
// };
// AddProperty(variable, property);
}
if (!variableRuntime.CollectGroup.IsNullOrEmpty())
{
//}
//if (!variableRuntime.CollectGroup.IsNullOrEmpty())
//{
var property = new PropertyState<string>(variable)
{
NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.CollectGroup", NamespaceIndex),
BrowseName = new QualifiedName("CollectGroup", NamespaceIndex),
DisplayName = "CollectGroup",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = variableRuntime.CollectGroup,
};
AddProperty(variable, property);
}
{
var property = new PropertyState<string>(variable)
{
NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark1", NamespaceIndex),
BrowseName = new QualifiedName("Remark1", NamespaceIndex),
DisplayName = "Remark1",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = variableRuntime.Remark1 ?? string.Empty
};
AddProperty(variable, property);
}
// var property = new PropertyState<string>(variable)
// {
// NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.CollectGroup", NamespaceIndex),
// BrowseName = new QualifiedName("CollectGroup", NamespaceIndex),
// DisplayName = "CollectGroup",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = variableRuntime.CollectGroup,
// };
// AddProperty(variable, property);
//}
//{
// var property = new PropertyState<string>(variable)
// {
// NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark1", NamespaceIndex),
// BrowseName = new QualifiedName("Remark1", NamespaceIndex),
// DisplayName = "Remark1",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = variableRuntime.Remark1 ?? string.Empty
// };
// AddProperty(variable, property);
//}
{
var property = new PropertyState<string>(variable)
{
NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark2", NamespaceIndex),
BrowseName = new QualifiedName("Remark2", NamespaceIndex),
DisplayName = "Remark2",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = variableRuntime.Remark2 ?? string.Empty
};
AddProperty(variable, property);
}
//{
// var property = new PropertyState<string>(variable)
// {
// NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark2", NamespaceIndex),
// BrowseName = new QualifiedName("Remark2", NamespaceIndex),
// DisplayName = "Remark2",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = variableRuntime.Remark2 ?? string.Empty
// };
// AddProperty(variable, property);
//}
{
var property = new PropertyState<string>(variable)
{
NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark3", NamespaceIndex),
BrowseName = new QualifiedName("Remark3", NamespaceIndex),
DisplayName = "Remark3",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = variableRuntime.Remark3 ?? string.Empty
};
AddProperty(variable, property);
}
//{
// var property = new PropertyState<string>(variable)
// {
// NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark3", NamespaceIndex),
// BrowseName = new QualifiedName("Remark3", NamespaceIndex),
// DisplayName = "Remark3",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = variableRuntime.Remark3 ?? string.Empty
// };
// AddProperty(variable, property);
//}
{
var property = new PropertyState<string>(variable)
{
NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark4", NamespaceIndex),
BrowseName = new QualifiedName("Remark4", NamespaceIndex),
DisplayName = "Remark4",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = variableRuntime.Remark4 ?? string.Empty
};
AddProperty(variable, property);
}
{
var property = new PropertyState<string>(variable)
{
NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark5", NamespaceIndex),
BrowseName = new QualifiedName("Remark5", NamespaceIndex),
DisplayName = "Remark5",
DataType = DataTypeIds.String,
ValueRank = ValueRanks.Scalar,
Value = variableRuntime.Remark5 ?? string.Empty
};
AddProperty(variable, property);
}
//{
// var property = new PropertyState<string>(variable)
// {
// NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark4", NamespaceIndex),
// BrowseName = new QualifiedName("Remark4", NamespaceIndex),
// DisplayName = "Remark4",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = variableRuntime.Remark4 ?? string.Empty
// };
// AddProperty(variable, property);
//}
//{
// var property = new PropertyState<string>(variable)
// {
// NodeId = new NodeId($"{variableRuntime.DeviceName}.{variableRuntime.Name}.Remark5", NamespaceIndex),
// BrowseName = new QualifiedName("Remark5", NamespaceIndex),
// DisplayName = "Remark5",
// DataType = DataTypeIds.String,
// ValueRank = ValueRanks.Scalar,
// Value = variableRuntime.Remark5 ?? string.Empty
// };
// AddProperty(variable, property);
//}
NodeIdTags.AddOrUpdate($"{variableRuntime.DeviceName}.{variableRuntime.Name}", variable);
parent?.AddChild(variable);
return variable;
}

View File

@@ -88,6 +88,19 @@ public partial class OpcUaServer : BusinessBase
protected override async Task InitChannelAsync(IChannel? channel, CancellationToken cancellationToken)
{
await UaInit().ConfigureAwait(false);
GlobalData.VariableValueChangeEvent += VariableValueChange;
Localizer = App.CreateLocalizerByType(typeof(OpcUaServer))!;
await base.InitChannelAsync(channel, cancellationToken).ConfigureAwait(false);
}
private async Task UaInit()
{
ApplicationInstance.MessageDlg = new ApplicationMessageDlg(LogMessage);//默认返回true
@@ -105,17 +118,13 @@ public partial class OpcUaServer : BusinessBase
}
m_server = new(this);
GlobalData.VariableValueChangeEvent += VariableValueChange;
Localizer = App.CreateLocalizerByType(typeof(OpcUaServer))!;
await base.InitChannelAsync(channel, cancellationToken).ConfigureAwait(false);
}
private void UaDispose()
{
m_server?.Stop();
m_server?.NodeManager?.SafeDispose();
m_server?.SafeDispose();
}
/// <inheritdoc/>
public override bool IsConnected()
{
@@ -134,13 +143,14 @@ public partial class OpcUaServer : BusinessBase
protected override void Dispose(bool disposing)
{
GlobalData.VariableValueChangeEvent -= VariableValueChange;
m_server?.Stop();
m_server?.SafeDispose();
UaDispose();
CollectVariableRuntimes?.Clear();
IdVariableRuntimes?.Clear();
base.Dispose(disposing);
}
protected override async Task ProtectedStartAsync(CancellationToken cancellationToken)
{
// 启动服务器。
@@ -174,7 +184,7 @@ public partial class OpcUaServer : BusinessBase
await Task.Delay(10000, cancellationToken).ConfigureAwait(false);
}
}
var varList = CollectVariableRuntimes.ToIEnumerableWithDequeue();
var varList = CollectVariableRuntimes.ToListWithDequeue();
foreach (var item in varList)
{
try