dotnet/wpf · error · ObjectDisposedException

SR.HwndSourceDisposed

Error message

SR.HwndSourceDisposed

What it means

HwndSource members call CheckDisposed, which throws ObjectDisposedException(null, SR.HwndSourceDisposed) when the source has already been disposed (_isDisposed is true). It signals that the operation requires a live HwndSource whose HWND and resources still exist. The message identifies the disposed HwndSource instance.

Solutions

  1. Check hwndSource.IsDisposed before using the instance and bail out or re-obtain the source.
  2. Unhook events and cancel pending Dispatcher operations when the window closes (override OnClosed) so callbacks don't touch a disposed source.
  3. Re-resolve the source with HwndSource.FromHwnd(visual) at time of use rather than caching it, and handle null.
  4. Wrap late callbacks in a liveness check on the associated Window (window.IsLoaded / window.IsDisposed equivalent).

Example fix

// before
private void OnBackgroundWorkDone()
{
    _hwndSource.AddHook(WndProc); // throws if window closed
}
// after
private void OnBackgroundWorkDone()
{
    if (_hwndSource == null || _hwndSource.IsDisposed)
        return;
    _hwndSource.AddHook(WndProc);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (source == null || source.IsDisposed) return;

Type guard

static bool IsUsable(HwndSource s) => s != null && !s.IsDisposed;

Try / catch

try
{
    _hwndSource.AddHook(WndProc);
}
catch (ObjectDisposedException)
{
    // window already closed; skip or re-acquire source
}

Prevention

When it happens

Trigger: Calling any HwndSource API (AddHook, RemoveHook, SizeToContent setter, RegisterKeyboardInputSink, RootVisual, etc.) after Dispose was called or after the window was closed/disposed during shutdown.

Common situations: Event handlers or hooks firing during application shutdown after the window closed; async callbacks (Dispatcher.BeginInvoke) completing after disposal; cached HwndSource references (from FromHwnd at startup) used long after the window closed.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/ca567e595b8f5473. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndSource.cs:2631

                    // handlers call methods on us.
                    //
                    // Note: as the HwndWrapper shuts down, the final few messages
                    // will continue to pass through our WndProc hook.
                    _isDisposed = true;
                }
            }
        }

        private void CheckDisposed(bool verifyAccess)
        {
            if(verifyAccess)
            {
//                 this.VerifyAccess();
            }

            if(_isDisposed)
            {
                throw new ObjectDisposedException(null, SR.HwndSourceDisposed);
            }
        }

        private bool IsUsable
        {
            get
            {
                return !_isDisposed && _hwndTarget is not null && !_hwndTarget.IsDisposed;
            }
        }

        private bool HasFocus
        {
            get
            {
                return UnsafeNativeMethods.GetFocus() == Handle;
            }
        }

View on GitHub (pinned to 81131a70a4)