doc.NewSolution(true) with Ladybug/Honeybee crashes Rhino

What’s the difference between _doc.NewSolution(true) and _doc.ScheduleSolution(1)?

I’m asking because doc.NewSolution(true) crashes Rhino for Grasshopper definitions with Ladybug/Honeybee.

This crashing might be the case because some Ladybug/Honeybee components use ExpireSolution()

On the other hand, _doc.ScheduleSolution(1) doesn’t work with an interactive application that I’m building. (One can drag a marker across a fitness landscape, with Grasshopper automatically updating itself to the marker’s position.)

doc.NewSolution(true) works in that case, but _doc.ScheduleSolution(1) causes the application to freeze.

That sounds serious, as ScheduleSolution is what you almost always want to use.

NewSolution(bool) immediately kicks off a new solution on the caller thread. This method is risky in case the new solution triggers the same behaviour, in which case you get an endless regression of new solutions triggering new solutions. Well, not endless, eventually you’ll crash with a stackoverflow exception. You can use this method in response to UI events (button clicks, menu item clicks, etc.) that are guaranteed to happen on the UI thread and that are guaranteed to not be recursive.

ScheduleSolution(int N) will start a timer which will try and trigger a new solution on the UI thread, N milliseconds after the current solution (if any) has completed. If multiple solutions are scheduled then the earliest one wins and the rest are cleared. It is the safe and responsible thing to do. So if this crashes, I’d love to know more.

Is there a ‘report crash’ window when this happens? If so, is there a .NET callstack text file on the desktop while the window is open? Can you upload that textfile?

1 Like

Thanks for your reply!

In the case of ScheduleSolution(int N) the window just doesn’t open and Grasshopper/Rhino freezes.
So no crash report unfortunately.

Apparently, some Honeybee components expire the solution, which might be part of the problem why NewSolution(bool) causes a crash.

Here’s the code I’m using. It’s really unclear to me why ScheduleSountion(int N) doesn’t work with my interactive application. Also I think the waiting should take care of crashes caused by recursion, at least in theory.

//Wait until the grasshopper solution in finished
while (_doc.SolutionState != GH_ProcessStep.PreProcess || _doc.SolutionDepth != 0) { }

_doc.NewSolution(true);
//_doc.ScheduleSolution(1);

//Wait until the grasshopper solution in finished
while (_doc.SolutionState != GH_ProcessStep.PostProcess || _doc.SolutionDepth != 0) { }

Well that’s an infinite tight loop right there. If that’s running on the UI thread then it will effectively block everything else going on on the UI thread.

You should not run loops waiting for the solution to start or complete, there are events on GH_Document you can handle for those.

I understand now!

In case 1, I’m running the wait loops with _doc.ScheduleSolution(1) on a background thread (separate from the UI), which works fine.

In case 2, the loops are not separate from the UI thread, and thus cause it to freeze.
It works with _doc.NewSolution(bool) because there’s no waiting, but that’s unsafe.
So in other words, I should be executing the recomputing of Grasshopper on a separate thread also in case 2.

It’s not obvious to me right now how to do that, since, in case 2, the user triggers re-computations all the time, but there should be a way.

Hi All,

I’m also trying to trigger a ScheduleSolution while having multiple threads.
In the case of multithreading so that the GUI doesn’t freeze, I’ve implemented a BackgroundWorker in my window and hooked its ProgressChanged event to interface with grasshopper’s UI.

However when I try to use ScheduleSolution that way (on the same thread where the top-level GH_Document is created) the whole thing freezes at waiting for SolutionState to turn to GH_ProcessStep.PostProcess. It gets stuck at GH_ProcessStep.PreProcess, which according to the documentation means it’s ready and waiting for a new solution, so that seems really weird because I had just scheduled a solution before.

Using NewSolution would have no problems, though as I understand from this discussion it is probably unsafe to do so.

Using ScheduleSolution on a thread different than the one in the UI will also work.

I can’t help without seeing the code that reproduces this. Please create the simplest example that shows this problem so I can run and debug it on my own machine.

ps. you can run NewSolution, just be sure to invoke it on the UI thread if your code is running elsewhere. Using NewSolution is mostly problematic if you are liable to call it again during that newly triggered solution. However, ScheduleSolution should absolutely be your first port of call since it side-steps all these issues.

Since NewSolution is safe enough if it is run in the UI thread, I will go ahead with that. Thanks.