All Grasshopper users know the pain that comes with accidentally setting off an enormous calculation, and realising we’ve done something wrong and need to cancel it.
Since Grasshopper is tied on to the Rhino process in Windows, and the whole thing is single threaded, it is very difficult programatically to allow users to cancel a calculation part-way through. Part of the reason is that the UI and the calculations share that same thread. When heavy calculations are running, there are basically no cycles spare to handle a ‘cancel’ button.
Rutten has implemented a workaround, however. By button-mashing the Esc key during calculations, some components can listen for this key and issue an ‘abort request’. This system isn’t perfect, but it has on numerous occasions saved me from needing me to completely kill and restart Rhino.
This functionality doesn’t happen automatically. The Esc key check only happens when specified within your code, so if you never check if the Esc key is down, it is impossible for the user to abort the solution whilst Grasshopper is churning through your component. We need to implement this functionality manually.
For many lightweight components, this isn’t critical. But if your component takes a long time to calculate, it’s more likely that the user will want to abort the solution while Grasshopper is calculating yours – since Grasshopper processes each component during calculation one at a time.
How to implement Esc behaviour
Grasshopper includes some useful methods to provide the behaviour we need. How it works is that, every once in a while, we check if the escape key is down as part of our calculations. If it is down, the user wants to cancel calculations. So we submit a cancel request to Grasshopper. It is then up to Grasshopper to act upon this request.
For a compiled component, we can implement the code within SolveInstance(), or within another calculation-heavy part of your code.
The following code is in C#:
GH_Document GHDocument = OnPingDocument();
A good place to put this code is within a loop within your component. Don’t call IsEscapeKeyDown() too often though, as it requires processing power to handle this method, which will slow down your component.
Since the GH_Document is likely constant for the life of the component instance, you could pull this out and calculate it
in the constructor* at the top of your SolveInstance() – since it’s a useful variable elsewhere anyway.
And for a rather interesting comment thread… http://www.grasshopper3d.com/forum/topics/emergency-top-for-solution-calculation