C# / .NET · recipe
Subscribe to data changes in C#
Create a Subscription with the publishing interval your consumer needs, add MonitoredItems with their own sampling interval, queue size and filter, then call ApplyChanges. Read back the revised parameters the server returns.
| Stack | OPCFoundation/UA-.NETStandard |
|---|---|
| Version | 1.5.378.156 stable, 2.0.0-preview.2 |
The code
var subscription = new Subscription(session.DefaultSubscription)
{
PublishingInterval = 1000, // delivery rate the consumer needs
KeepAliveCount = 10,
LifetimeCount = 100,
MaxNotificationsPerPublish = 1000,
PublishingEnabled = true,
Priority = 10,
};
session.AddSubscription(subscription);
subscription.Create();
Console.WriteLine($"revised publishing interval: {subscription.CurrentPublishingInterval}");
var item = new MonitoredItem(subscription.DefaultItem)
{
StartNodeId = new NodeId(2258),
AttributeId = Attributes.Value,
SamplingInterval = 250, // how often the server looks
QueueSize = 10,
DiscardOldest = true,
Filter = new DataChangeFilter
{
Trigger = DataChangeTrigger.StatusValue,
DeadbandType = (uint)DeadbandType.Absolute,
DeadbandValue = 0.5,
},
};
item.Notification += (mi, e) =>
{
foreach (var dv in mi.DequeueValues())
Console.WriteLine($"{dv.Value} [{dv.StatusCode}] {dv.SourceTimestamp:O}");
};
subscription.AddItem(item);
subscription.ApplyChanges();
Console.WriteLine($"revised sampling interval: {item.Status.SamplingInterval}");
await Task.Delay(5000);
subscription.Delete(true);
What it prints
revised publishing interval: 1000
revised sampling interval: 250
08/09/2026 03:45:00 [Good] 2026-09-08T03:45:00.1020000Z
08/09/2026 03:45:01 [Good] 2026-09-08T03:45:01.1040000Z
Notes
- Nothing happens until ApplyChanges. Adding items without it is a common first mistake.
- Read CurrentPublishingInterval and item.Status.SamplingInterval after creation. You requested; the server revised, and believing your request is how clients end up wrong about their own sample rate.
- DequeueValues drains the item's queue. If it returns more values than you expect per notification, your sampling interval is faster than your publishing interval, which is fine, but size the queue for it.
- Percent deadband needs EURange on the node. Absolute is the safe default.
- Keep the number of distinct publishing intervals small; each one is another subscription server-side.
What breaks first
Samples are missing but every status code reads Good
The queue overflowed between publishes. Increase QueueSize, slow SamplingInterval, or apply a deadband.
GoodOverloadThe queue overflowed between publishes. Increase QueueSize, slow SamplingInterval, or apply a deadband.
Other recipes in this stack
Concepts on this page
Last verified 7 September 2026 against OPC UA 1.05.07. OPC UA Connect is an educational resource and is not affiliated with the OPC Foundation.