GLWpfControl icon indicating copy to clipboard operation
GLWpfControl copied to clipboard

Error When Disposing GlWpfControl on a Thread Other Than Main

Open anose001 opened this issue 1 year ago • 9 comments

The view containing my GlWpfControl throws the error

OpenTK.Windowing.GraphicsLibraryFramework.GLFWException: 'You can only dispose windows on the main thread. The window needs to be disposed as it cannot safely be disposed in the finalizer.'

in DXGLContext.cs at GlfwWindow?.Dispose(); in the Dispose() method when navigating views in my application. I am not closing any windows and my application keeps running.

I tried to keep it on the main thread with a Dispatcher call explicitly calling out the Dispose() method on MyGlWpfControl.

    protected void OnClosed(object o, RoutedEventArgs e)
    {
        Application.Current.Dispatcher.Invoke(() =>
        {
            MyGlWpfControl.Render -= OnRender;
            MyGlWpfControl.Dispose();   
        });
    }

but to no effect. Removing the OnClosed() method gives the same outcome.

Once the view is changed I believe that the garbage collector frees the resource on some thread other than the main thread.

I assume there is a good reason to dispose the window on the main thread but don't really know what that is right now.

What is the recommended approach to dispose a GlWpfControl while my application is running?

anose001 avatar Jul 18 '24 18:07 anose001

You need to dispose the control on a thread that has the OpenGL context associated with the control current. Otherwise opengl functions will fail (there is also glfw reasons on macOS (I think) where you need to be on the main thread). You can't have a context current on two threads at once, and because the render thread is likely using the context a lot of the time and syncing with it is hard, so it's easiest to keep it all on the main thread.

But it's possible that we have a bug where is using multiple controls will cause the wrong OpenGL context to be current when disposing, and I think we don't make sure the context is current when disposing, so there is a possible bug there.

NogginBops avatar Jul 18 '24 18:07 NogginBops

@anose001 were you able to find the workaround for the disposal issue? I'm running into the same issue.

simfero avatar Aug 09 '24 04:08 simfero

@simfero, I moved forward to the next part of the project and I am not sure I remember. Did the latest GlWpfConotrol release 4.3.2 fix the crash issue for you? Are you manually disposing off the control?

anose001 avatar Aug 09 '24 05:08 anose001

@anose001 I get this exception with 4.3.2. I have tried manually disposing and I get the same exception.

simfero avatar Aug 12 '24 20:08 simfero

@simfero are you disposing on the main thread?

NogginBops avatar Aug 12 '24 22:08 NogginBops

@NogginBops I checked thread ids and it's not disposing on the main thread.

simfero avatar Aug 13 '24 00:08 simfero

You need to call dispose on the main thread

NogginBops avatar Aug 13 '24 08:08 NogginBops

@NogginBops It's being disposed on GE Finalizer Thread.

However, everything works as expected with this branch: https://github.com/opentk/GLWpfControl/pull/135

simfero avatar Aug 13 '24 22:08 simfero

It's being disposed on GE Finalizer Thread.

You can't rely on the finalizer to dispose of the control, you are going to have to call dispose yourself from the main thread. I'm not sure there is anything in #135 that would allow you to dispose the control from the finalizer thread, so not sure what that is about.

NogginBops avatar Aug 13 '24 22:08 NogginBops

I think most of the dispose issues have been fixed. Disposing the control on threads other than the main thread is not something we support, so that is not going to work.

NogginBops avatar Oct 31 '24 20:10 NogginBops