跳到主要内容

添加 MonitoredItem

前置阅读

sub.Add(...)

public uint Add(
string nodeId,
AttributeId attribute = AttributeId.Value,
double samplingIntervalMs = -1.0);
参数默认说明
nodeId监控的 NodeId
attributeValue (13)监控的 Attribute
samplingIntervalMs-1 (跟订阅)服务端采样间隔. 0 = 尽快

返回: uint MonitoredItem handle (本地句柄, 用于后续 Modify / Remove)

异常: OpcUaException (BadNodeIdUnknown 等)

uint h  = sub.Add("ns=2;s=Temperature");
uint h2 = sub.Add("ns=2;s=Pressure", AttributeId.Value, samplingIntervalMs: 100);

sub.AddMany(nodeIds, attribute)

一次 RPC 添加多个 MI, 比循环 Add 快得多:

public IReadOnlyList<(uint handle, StatusCode status)> AddMany(
IReadOnlyList<string> nodeIds,
AttributeId attribute = AttributeId.Value);
var nodes = Enumerable.Range(1, 100).Select(i => $"ns=2;s=T{i}").ToList();
var results = sub.AddMany(nodes);
for (int i = 0; i < nodes.Count; i++)
{
if (results[i].status == StatusCode.Good)
Console.WriteLine($" {nodes[i]} -> handle={results[i].handle}");
else
Console.WriteLine($" {nodes[i]} FAILED: {results[i].status}");
}

性能: 100 个 MI 用 AddMany 约 1 次 RPC (~10 ms), 用循环 Add 约 100 次 RPC (~500-1000 ms).


DataChanged 事件 args

订阅的回调参数 DataChangeEventArgs:

字段类型说明
MonitoredItemHandleuint触发的 MI 句柄
NodeIdstring该 MI 的 NodeId
ValueStringstring值的字符串表示 (预抽取, 跨线程安全)
DataTypeNamestring内置数据类型枚举名 (如 Double)
StatusStatusCodeDataValue 的 Status
SourceTimestampDateTime?数据源时间戳
ServerTimestampDateTime?服务端时间戳
安全设计

ValueString / DataTypeName 已在 C 层 Publish 线程同步抽取, 跨线程使用安全. 不再暴露原始 DataValue 指针, 避免 use-after-free 闪退.


移除

sub.Remove(handle);
sub.RemoveByNodeId("ns=2;s=Temperature"); // 按 NodeId 移除全部对应

不同 Attribute 的监控

除了默认监控 Value, 也能监控 Status / Quality:

sub.Add("ns=2;s=T1", AttributeId.Value);
sub.Add("ns=2;s=T1", AttributeId.StatusCode); // 只关心状态变化

DataChangeFilter (死区)

当前 SDK 默认不设 filter (任何变化都推). 如需 Absolute / Percent 死区, 走底层 API (后续版本会暴露).

下一步