C# ObjectTable.FindByUserString bug


I believe there is a bug in the following RhinoCommon function. ObjectTable.FindByUserString method.

The parameters I am giving the function are:
rDoc.Objects.FindByUserString(“F”, frameName, true, false, true, new ObjectEnumeratorSettings() { HiddenObjects = true }); where frameName is just a not null, not empty string.

Note that my application is multithreaded. This function is called some 100 times, in sequence, filtering a relatively large number of objects in the model.
BUT, before you say that it is due to it being multithreaded, and there are clashes as this function must be called from the UI thread, please note:
1- I am calling this function wrapped inside an action that I tell to run on Rhino UI thread using the dispatcher.
2- I added to my debug session the following code right above calling this function. The exception is never thrown, which means that the RhinoApp.InvokeRequired ALWAYS returns false

if (RhinoApp.InvokeRequired) 
throw new InvalidOperationException($"The function should be running on the UI thread.");

3- I have similar functionality that is also called a number of times using my same custom wrappers to ensure that the calls are made in the Rhino thread. They never fail. These include calls to functions such as Objects.GetSelectedObjects, Objects.FindByFilter, Objects.FindByLayer, adding, removing objects. They never fail. It is exclusively this function that fails.

The errors I get are:

call stack
RhinoCore.dll!CRhinoObjectIterator::Next() Line 772
at D:\BuildAgent\work\commercial\src4\rhino4\rhino3Object.cpp(772)
rhcommon_c.dll!CRhinoDoc_LookupObjectsByUserText(const wchar_t * _key, const wchar_t * _value, bool compareCasing, bool searchGeometry, bool searchAttributes, CRhinoObjectIterator * iterator, ON_SimpleArray<CRhinoObject *> * pObjectArray) Line 1176
at D:\BuildAgent\work\commercial\src4\DotNetSDK\rhinocommon\c\rh_doc.cpp(1176)
[Managed to Native Transition]

Exception I get in Visual Studio on the C# side
Exception thrown: read access violation.
this->m_current was nullptr.

One possible approach to resolve the issue is to add additional null reference checks to the code to ensure that the required objects are not null before attempting to use them. It’s also possible that the issue is related to the multithreading, even though the current code is wrapped in an action that is executed on the UI thread. To ensure that the function is executing correctly on the UI thread, it may be helpful to use a tool like a Mutex to synchronize access to the code.

Hello @farouk.serragedine

I appreciate your reply. Please note that:
1- The objects are never null.
2- It is not a multithread problem.

I have just made the following debug changes in my code. Instead of calling the ObjectTable.FindByUserString method (with the given signature!), I wrote a quick function to wrap the functionality a bit differently:

        public RhinoObject[] Custom_FindByUserString(string key, string value, ObjectEnumeratorSettings objectEnumeratorSettings)
            List<RhinoObject> ret = new List<RhinoObject>();
            foreach (RhinoObject o in rDoc.Objects.GetObjectList(objectEnumeratorSettings))
                var attrs = o.Attributes.GetUserStrings();
                if (attrs[key] == value) ret.Add(o);
            return ret.ToArray();

By swapping the calls to ObjectTable.FindByUserString with this function, it is not failing in my tests so far. But this is MUCH slower because of all the marshalling that needs to be done back and forth between native and managed code.

1 Like

Hi @scudelari,

Can you provide some simple sample code, that we can run here, that reproduces the issue?

– Dale

I’ll work on this in the weekend and I will get back to you.

Thanks, @dale

Hi @dale,

I just wanted to update that I didn’t still have the time to do this.