DataValue
DataValue 包装一次 Read 返回的全部信息: 值 + 状态 + 时间戳.
配套
- 内部值容器请看 Variant.
- 标准节点常量请看 WellKnownNodes.
公共属性
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 值 | Value | Variant | R | 实际值 (可能 null) |
Status | StatusCode | R | 数据质量 Good / Bad* / Uncertain* | |
| 时间戳 | SourceTimestamp | DateTime? | R | 数据源打的时间戳 |
ServerTimestamp | DateTime? | R | 服务端收到时打的时间戳 | |
SourcePicoseconds | ushort | R | SourceTimestamp 的皮秒补充 | |
ServerPicoseconds | ushort | R | 同上 |
构造
通常由 SDK 内部构造 (从 Read / ReadHistory 返回). 用户也可以构造用于 HistoryUpdate:
var dv = new DataValue(
value: new Variant(25.3),
status: StatusCode.Good,
sourceTimestamp: DateTime.UtcNow);
用法
using var dv = ua.Read("ns=2;s=Temperature");
// 检查质量
if (dv.Status != StatusCode.Good)
{
Console.WriteLine($"Bad value: {dv.Status}");
return;
}
// 检查值
if (dv.Value == null || dv.Value.IsNull)
{
Console.WriteLine("Null value");
return;
}
// 取值
double temp = dv.Value.AsDouble;
DateTime t = dv.SourceTimestamp ?? DateTime.UtcNow;
Console.WriteLine($"{t:O}: {temp} °C");
StatusCode 重点值
| 值 | 含义 |
|---|---|
Good (0x00000000) | 一切正常 |
Uncertain* (0x40000000+) | 不确定但可用 (例如传感器超量程) |
Bad* (0x80000000+) | 数据无效 |
BadCommunicationError | 通讯失败 |
BadNodeIdUnknown | 节点不存在 |
BadNotReadable | 该 Attribute 不可读 |
业务代码必须检查 Status, 不能假设 Good.
时间戳含义
SourceTimestamp— 数据真实产生时间 (传感器采样时刻 / 计算时刻). 历史 / 趋势 / 同步用这个.ServerTimestamp— 服务端收到 / 处理时间. 用于诊断网络延迟. 一般不用于业务.
如果服务端没设 SourceTimestamp, 它就是 ServerTimestamp 的副本.
内存所有权
DataValue 持有 native handle. 从 ua.Read / ua.ReadHistory / ua.ReadMany 返回的都需要 Dispose.
最佳实践:
// 单个
using var dv = ua.Read("ns=2;s=T1");
// 批量
var dvs = ua.ReadMany(nodes);
try { /* 用 */ } finally { foreach (var dv in dvs) dv?.Dispose(); }
// 或 using 扩展
foreach (var dv in dvs) using (dv) { /* ... */ }
漏 Dispose 会泄漏 native 内存 (定时跑 100k+ 次会涨内存).