Is there a workaround to making API calls in threads?

Background

In an external process using gRPC/pyMechanical, we want to invoke a function in Mechanical. Midway through the function, we want to possibly "interrupt" and request more information/interact with the external process. (Using another socket.) We are not able to sleep/wait on a socket connection in the remote call as this freezes the UI. So we turned to waiting on this socket in another thread in Mechanical.

The Issue

Our issue arises from calls to the API in a non-UI thread. We understand and have read the various warnings regarding race conditions and such in the documentation, but these appeared to be written as general warnings. We intended to take our own precautions with locking mechanisms and freezing the UI during API calls so this does not occur. However, it appears that any access to some non-read API calls in non-UI threads causes unexpected behavior/crashes.

We've had some success with API calls within a nested UI "thread", started with InvokeUIThread, that is itself within a thread started with InvokeBackground, but this still produces strange UI behavior for certain calls.

For example:

  1. def works_in_background():
  2. # "Read" calls work in background
  3. analysis = DataModel.AnalysisByName("Static Structural")
  4.  
  5. def works_in_nested_ui_thread():
  6. # Creating an object in an analysis "works" in a UI thread nested in a background thread.
  7. # Calling this directly in the background thread does not work.
  8. pressure = analysis.AddPressure()
  9.  
  10. def doesnt_work_in_nested_ui_thread():
  11. # Assigning properties does not work in a nested UI thread.
  12. pressure.Location = DataModel.GetObjectsByName('BracketTop')[0]
  13.  
  14. # Uncommenting this to call in the nested UI thread does not work.
  15. # May have to restart to get the UI working again.
  16. #doesnt_work_in_nested_ui_thread()
  17.  
  18. # Blocking, which is fine.
  19. ExtAPI.Application.InvokeUIThread(works_in_nested_ui_thread)
  20.  
  21. # Uncommenting this to call in the background thread does not work.
  22. # "Works" above when ran with InvokeUIThread.
  23. #works_in_nested_ui_thread()
  24.  
  25. ExtAPI.Application.InvokeBackground(action=works_in_background)

I was imagining InvokeUIThread was calling the given function in the UI thread, with whatever locks/mechanisms necessary to keep the UI running smoothly. There seems to be more going on.

  1. Have we misunderstood the documentation? Is it true that it's impossible to make any API calls in a non-UI thread, regardless of what precautions are taken to avoid race conditions?
  2. Is this nested InvokeUIThread workaround a dead-end?
  3. If so, is there another way to run certain sections of code, those including API calls, safely in a background thread? (Perhaps writing a C# extension that is able to handle those calls safely?)

We are using Mechanical 2024 R2.

Welcome!

It looks like you're new here. Sign in or register to get started.