OPCFoundation / UA-.NETStandard

OPC Unified Architecture .NET Standard
Other
1.96k stars 946 forks source link

Async problem in class Opc.Ua.NodeIdDictionary, freezing Reference Client #1333

Open CKa77 opened 3 years ago

CKa77 commented 3 years ago

Type of Issue [X] Bug [ ] Enhancement [ ] Compliance [ ] Question [ ] Help wanted

Describe the Issue

The reference C# client was most of the times I connected to Integration Object's free OPC UA Server Simulator freezing and not showing the nodes and tags in the browser window. Sometimes, but rarely it worked, and when trying to restart the reference client it would just freeze after connecting.

To Reproduce Steps to reproduce the behavior:

  1. Compile Reference Client and start it from Visual Studio Debugger (press F5)
  2. Download, install and start Integrated Objects' OPC UA Server Simulator
  3. Connect with the Reference Client to the OPC UA Server Simulator address
  4. Most of the time, the Reference Client's UI will freeze completely

Expected behavior Most of the times, the Reference Client's UI will freeze

Code snippets I managed to get the Reference Client to work reliably, by introducing lock-statements for the variable 'm_numericIds' in class Opc.Ua.NodeIdDictionary, in methods Add(NodeId, T value) and TryGetValue(NodeId key, out T value), as follows:

In Add() method, the following case-statement was changed as follows:

case IdType.Numeric:
                {
                    ulong id = ((ulong)key.NamespaceIndex) << 32;
                    id += (uint)key.Identifier;

                    lock (m_numericIds)
                    {
                        m_numericIds.Add(id, value);
                    }

                    return;
                }

And in TryGetValue method, the following code was used:

case IdType.Numeric:
                {

                    ulong id = ((ulong)key.NamespaceIndex) << 32;
                    id += (uint)key.Identifier;

                    bool _result = false;

                    lock (m_numericIds)
                    {
                       _result = m_numericIds.TryGetValue(id, out value);
                    }

                    return _result;

                    //return m_numericIds.TryGetValue(id, out value);

Environment (please complete the following information):

Additional context After the changes shown above, the Reference Client was working. I do not say that this is necessary the absolute correct fix here, but I think this shows where the problem is. A fix to the master copy would be good to implement.

mrsuciu commented 3 years ago

Needs to be checked