How to stop a Grasshopper component in the middle of calculations

Moving away from the recent work in NodeJS back to Grasshopper has brought me onto a sore point with the majority of calculations I try to perform. Most of my work requires some intense spatial analysis but can take a rather long time to complete. Sometimes I connect incorrect data by mistake and calculations try to run and end up crashing the whole component, particularly during development, and I end up having to restart Rhino/Grasshopper to try again. So on both a development point of view and a usability point of view, the ability to stop a component while it’s attempting to calculate would be a very handy feature.

Luckily, such a solution exists. Instead of having to implement anything ourselves, Mr Rutten has kindly provided us with functionality to check if the escape key is being pressed, which we can capture and utilise for our own means. The code itself is a very simple if statement calling the Grasshopper document and asking if the escape key is down, and a one extra line to abort the calculations.

The code

if(GH_Document.IsEscapeKeyDown())
{
    OnPingDocument().RequestAbortSolution(); //Abort the calculations
}

This is best placed inside a loop, if you’re running one. If you place it inside the solve instance outside of a loop (and have looping code later one), this would run once, presumably fail (unless you’re the type of person who likes holding the escape down for fun), and then never be executed again (thus never aborting calculations later). So putting this inside a loop is best.

However, be careful when you use this. While it’s all well and good being able to cancel calculations, there are additional processing costs associated with pinging the keyboard and asking if the escape key is down every iteration, so if your calculation is fairly quick (even if it’s incorrect) I’d recommend not using this method, as this will only slow it down potentially unnecessarily.

Multi-threading this solution

One way to escape the power drain of implementing the escape key is to multi-thread it, so that one thread handles the UI and one thread handles the calculations. This would allow one thread to handle pinging the keyboard to find out if the escape key has been pressed and one thread to carry on calculations at full speed.

Multi-threading can be a complex task, as you have to continually ensure variables are thread safe, however, in a very simple way, this is how you can multi-thread this escape key solution (but if you want to do it properly, you’ll need to provide the proper thread safe precautions).

private bool threadFinished = false;
protected override void SolveInstance(IGH_DataAccess DA)
{
    System.Threading.Thread myThread = new System.Threading.Thread(RunMyThread);
    myThread.Start()
    
    while(!threadFinished)
    {
        if(GH_Document.IsEscapeKeyDown())
        {
            OnPingDocument().RequestAbortSolution();
            myThread.Abort();
            threadFinished = true;
        }
    }
}

private void RunMyThread()
{
    //Do some stuff
    threadFinished = true; //After calculations to break out of the while loop in solve instance
}

Leave a Reply

Your email address will not be published. Required fields are marked *