OPCFoundation / UA-.NET-Legacy

OPC Foundation Unified Architecture .NET Reference Implementations
330 stars 298 forks source link

Memory consumption MonitoredItem #185

Open Luigie opened 4 years ago

Luigie commented 4 years ago

Hello,

The MonitoredItemNotifications are not cleaned up after they have been processed. image Memory is getting full.

private SemaphoreSlim sem = new SemaphoreSlim(1); public void RegisterTagValueHandler(ITagDTO tag, IOpcUaItemDTO opcUaItem) { try { sem.Wait(); Subscription subscription; if (tag.IsReadable && subscriptions.TryGetValue(opcUaItem.OpcUaSubscriptionId.Value, out subscription)) { RegisterTagValueHandler(tag, opcUaItem, subscription); subscription.ApplyChanges(); } } catch (Exception ex) { LogError("Failed to register tag value handler", ex); throw; } finally { sem.Release(); } }

Register the items we want to monitor for data changes. ` private void RegisterTagValueHandler(ITagDTO tag, IOpcUaItemDTO opcUaItem, Subscription subscription) { try { var handler = new TagHandler(this) { NodeId = opcUaItem.NodeId, TagId = tag.Id, IsCumulative = tag.IsCumulative, DataType = tag.DataType, TimeZone = OpcUaServer.TimeZone }; var monitoredItem = new MonitoredItem(subscription.DefaultItem); monitoredItem.AttributeId = Attributes.Value; monitoredItem.StartNodeId = opcUaItem.NodeId; monitoredItem.CacheQueueSize = opcUaItem.QueueSize; monitoredItem.QueueSize = (uint)opcUaItem.QueueSize; monitoredItem.SamplingInterval = opcUaItem.SampleInterval; if ((DeadbandType)Enum.ToObject(typeof(DeadbandType), tag.DeadbandType) != DeadbandType.None && tag.DeadbandValue.HasValue && tag.DeadbandValue.Value > 0) { var filter = new DataChangeFilter(); filter.Trigger = DataChangeTrigger.StatusValue; filter.DeadbandType = (uint)tag.DeadbandType; filter.DeadbandValue = tag.DeadbandValue.Value; monitoredItem.Filter = filter;
}

            monitoredItem.Notification += handler.MonitoredItem_Notification;
            subscription.AddItem(monitoredItem);

            handler.MonitoredItem = monitoredItem;

            tagHandlers.Add(tag.Id, handler);

            LogInfo?.Invoke($"Tag value {tag.Name} with node id = {opcUaItem.NodeId} will be monitored!");
        }
        catch (Exception ex)
        {
            LogError?.Invoke($"Can not apply filter for nodeId:{opcUaItem.NodeId}. The item will not be monitored!", ex);
        }
    }`

Items are being dequeued and send to the correct handler.

public void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e) { Handle(monitoredItem, monitoredItem.DequeueValues()); }

` public override void Handle(MonitoredItem monitoredItem, IEnumerable dataValues) { client.LogTrace?.Invoke($"Tag values for node {NodeId } received");

    }`

Why are the notifications not cleand up when they are processed? Do I have to change cofiguration or dispose something?