Rhino Inside - Fatal app crashes when disposing headless documents

Hey, I wonder if I could get some clarity on the threading requirements for using Rhino.Inside to create and dispose headless documents.

I’m seeing some weird behaviour where the disposal of the RhinoDoc is causing my application to crash without a managed (.NET) exception for me to handle…

Here’s a minimal code sample that reproduces my issue. Regardless of the 3dm file you import, will crash on the line that disposes the open document, and the line “Success” will never print.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Rhino;
using Rhino.DocObjects;
using Rhino.Runtime.InProcess;

namespace RhinoInsideCrash
{
    class Program
    {
        static Program()
        {
            RhinoInside.Resolver.Initialize();
            Console.WriteLine($"Loading Rhino @ {RhinoInside.Resolver.RhinoSystemDirectory}");
        }

        [System.STAThread]
        static async Task Main(string[] args)
        {
            await RhinoProgram.Run();
            Console.WriteLine("Success!");
        }

        static class RhinoProgram
        {
            public static async Task Run()
            {
                //This is on the Main thread
                using (new RhinoCore([], WindowStyle.NoWindow))
                {

                    RhinoDoc open = RhinoDoc.CreateHeadless(null);
                    try
                    {
                        open.Import(@"C:\Users\Jedd\Documents\RhinoInsideCrash\Sample.3dm");

                        //Do something that actually interacts with the document...
                        List<RhinoObject> rhinoObjects = open.Objects.GetObjectList(ObjectType.AnyObject)
                            .ToList();

                        // Do *something* async.
                        // We have to use ConfigureAwait(false) here because Rhino will hog the main thread. Note, this does mean we'll be calling Dispose on a worker thread...
 
                        await Task.Delay(100).ConfigureAwait(false);
                    }
                    finally
                    {
                        Console.WriteLine("Done some stuff, about to dispose");
                        open?.Dispose(); //This line causes a fatal crash...
                    }
                }
            }
        }
    }
}

I thought that perhaps there’s some requirement to create and dispose the document on the same thread. So I did try wrapping all the code after the new RhinoCore in a Task.Run to keep everything on a worker thread. But same result…

I also thought, well maybe it’s not safe to use worker threads to create/dispose documents… But interestingly, if you import a non .3dm file (like a .obj, or .stl file) then the dispose works reliably.

I’ve also tried using RhinoDoc.OpenHeadless instead of RhinoDoc.CreateHeadless + RhinoDoc.Import

Same results.


So what gives?

Ultimately my goal is to be able to open and close a headless document, while performing some kind of await async action while it’s open…

Here’s my full .NET solution. I’m using Rhino.Inside 8.0.7-beta, and Rhino 8.22.25210.13001 (2025-07-29)

RhinoInsideCrash.zip (24.5 KB)

Steps to reproduce.

  1. Open solution

  2. restore

  3. build

  4. run

  5. observe non-zero exit code in console, and no “success” message gets printed…

Interestingly, the same code appears to run successfully with with rhino inside 7.0.0

But not 8.0.x or 9.0.x versions…

@fraguada @eirannejad any thoughts?
The minimal code sample I’ve provided reliably re-creates the crash I’m seeing.

Hi @Jedd_Morgan,

I’ll try to get to this sometime this week.

Thanks,

– Dale

1 Like

Hi @Jedd_Morgan,

I can repeat the exception, and I’ve logged the issue:

Thanks,

– Dale

1 Like

Thanks Dale,
We have a workaround now (we’re simply letting our app crash, and handling it gracefully), so this is now low priority from us!