Professional OPC
Development Tools


Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

Console Application - Subscribing To Large Number of Tags and Storing of Values

21 Feb 2022 09:49 #10642 by neilcooley
The following user(s) said Thank You: support

Please Log in or Create an account to join the conversation.

20 Feb 2022 16:59 #10638 by support
Yes, the dictionary object is the right choice here. There is no need to be concerned about the speed, it is more than satisfactory for this purpose.

Please have a look at the code below, I hope it helps:
' This example shows how to store current state of the subscribed items in a dictionary.
Imports System.Threading
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.OperationModel
Namespace DocExamples.DataAccess._EasyDAClient
    Partial Friend Class SubscribeMultipleItems
        Public Shared Sub StoreInDictionary()
            Using client = New EasyDAClient()
                AddHandler client.ItemChanged, AddressOf client_ItemChanged_StoreInDictionary
                client.SubscribeMultipleItems(New DAItemGroupArguments() {
                    New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Random", 1000, Nothing),
                    New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Ramp (1 min)", 1000, Nothing),
                    New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Trends.Sine (1 min)", 1000, Nothing),
                    New DAItemGroupArguments("", "OPCLabs.KitServer.2", "Simulation.Register_I4", 1000, Nothing)
                Console.WriteLine("Processing item changed events for 1 minute...")
                Dim startTickCount As Integer = Environment.TickCount
                    Thread.Sleep(5 * 1000)
                    ' Each 5 seconds, display the current state of the items we have subscribed to.
                    SyncLock _serialize
                        For Each pair As KeyValuePair(Of DAItemDescriptor, DAVtqResult) In _vtqResultDictionary
                            Dim itemDescriptor As DAItemDescriptor = pair.Key
                            Dim vtqResult = pair.Value
                            Console.WriteLine($"{itemDescriptor}: {vtqResult}")
                        ' The code above shows how you can process the complete contents of the dictionary. In other
                        ' scenarios, you may want to access just a specific entry in the dictionary. You can achieve that
                        ' by indexing the dictionary by the item descriptor of the item you are interested in.
                    End SyncLock
                Loop While Environment.TickCount < startTickCount + 60 * 1000
            End Using
        End Sub
        ' Item changed event handler
        Private Shared Sub client_ItemChanged_StoreInDictionary(ByVal sender As Object, ByVal e As EasyDAItemChangedEventArgs)
            SyncLock _serialize
                ' Convert the event arguments to a DAVtq result object, and store it in the dictionary under the key which
                ' is the item descriptor of the item this item changed event is for.
                _vtqResultDictionary(e.Arguments.ItemDescriptor) = CType(e, DAVtqResult)
            End SyncLock
        End Sub
        ' Holds last known state of each subscribed item.
        Private Shared ReadOnly _vtqResultDictionary As New Dictionary(Of DAItemDescriptor, DAVtqResult)
        ' Synchronization object used to prevent simultaneous access to the dictionary.
        Private Shared ReadOnly _serialize As New Object
    End Class

We also have pre-existing example of "loggers". They use somewhat different approach from what you suggested, but are still worth looking at:

Best regards

Please Log in or Create an account to join the conversation.

20 Feb 2022 09:09 #10637 by neilcooley
Many thanks for the prompt reply.

I wish to subscribe to the data and update a internal table, the idea is then every 5 seconds we log the values to a database (SQL, or MYSQL, or Access) or a CSV file - the destination is undecided but for now we can assume its a database.

Currently I am using VB.Net. I have seen that a dictionary object might be what i am looking for but i dont know if this would be fast enough to store the data values.


Please Log in or Create an account to join the conversation.

20 Feb 2022 08:51 #10636 by support

can you describe a bit more about how the values will then be processed. I mean, if you had the code that keeps the data structure updated, what then? Do you want to have some code that also reacts to every change, or do you want to have some parallel processing that would, for example, periodically examine the data as a whole and do something processing on them? Maybe a wider picture of what you want to achieve would help.

It is certainly doable, and too complicated. If I do not find an example, I would be happy to create one.

Is it in C# ?
Best regards

Please Log in or Create an account to join the conversation.

19 Feb 2022 20:50 #10635 by neilcooley
I am a regular user of OPC Labs for WinForms and quite regular use a list view to display the real time status of the values.

I am now developing a console application and whilst i know how to register multiple tagas and fire the change event, i am wondering if there is a example that shows how to store the tag name, value, quality and timestamp into a array list which then updates when the change event occurs?

Do you have a example or suggestions?


Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.082 seconds