Eto python async / multithreading (prevent UI from freezing)

Hey hi there everyone,

I recently started working with Eto in ironpython (still in Rhino 7 and therefore python 2.7) and reached a point that I just cannot figure out and found no useful information on:

I am basically making an REST API post, that can take quite some time to finish.

I trigger the call by subscribing to a button, but as soon as i run it the main layout freezes until the call is returned.

I tried different ways of solving it with libraries like asyncio or threading, but if I just do the call with these libraries (not surprisingly) that doesn’t change that problem
I can’t imagine, that I have to write the whole eto UI asynchronously from the ground up to make that work and I also don’t have experience with that …

I also found this method on the Eto documentation, but couldn’t figure out how to use it… especially since in the python example files there is never an “Application” class declared.
[Application.AsyncInvoke Method]

If someone here has experience or any idea/resource how to solve that and prevent the Eto UI from freezing while doing longer calculations/api calls or whatever, would be very grateful for any hint!

I’m not sure this is helpful, but when I’m coding a long-running calculation as part of a command, I put the long running calculation on a background thread, and make calls to RhinoApp.Wait() to keep the UI responsive. How that translates to IronPython, I’m not sure.

Thanks a lot for the response - it was a hint in the right direction and I figured it out with a fresh mind today in the morning !

That multithreading works with C# and I can import the python threading library made me think that should work as well with ironpython

If someone else ever runs into a similar problem, my mistake was the following:

My original code looked like this (the function is subscribed to a dropdown menu “combobox” close event):

from threading import Thread

# lots of code

def OnModelSelected(self, sender, e):
      modelName = self.models_combobox.DataStore[self.models_combobox.SelectedIndex] 
      
      t1 = Thread(target = self.WebUIInfo.setModel(modelName))
      t1.start()

So the problem here seems to be, that I tried to pass a variable modelName into the target method of the thread self.WebUIInfo.setModel() (so basically a syntax error)
But the interpreter somehow did not throw a warning or an error and even ran the code fine - just not on a separate thread

However I managed to fix it by passing the variable to the class holding the method instead and then it runs the method on a new thread and neither the main window nor the Eto window are locked

Code:

from threading import Thread

# lots of code


def OnModelSelected(self, sender, e):
      modelName = self.models_combobox.DataStore[self.models_combobox.SelectedIndex] 
      
      self.WebUIInfo.currentModel = modelName
        
      t1 = Thread(target = self.WebUIInfo.setModel)
      t1.start()
1 Like