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
- Check hwndSource.IsDisposed before using the instance and bail out or re-obtain the source.
- Unhook events and cancel pending Dispatcher operations when the window closes (override OnClosed) so callbacks don't touch a disposed source.
- Re-resolve the source with HwndSource.FromHwnd(visual) at time of use rather than caching it, and handle null.
- 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
- Check IsDisposed before every use of a cached HwndSource.
- Unhook events and cancel pending Dispatcher work in OnClosed.
- Resolve the source fresh via HwndSource.FromHwnd at time of use instead of caching.
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
- SR.CantSetOwnerToClosedWindow
- SR.NotAllowedBeforeShow
- SR.ReshowNotAllowed
- CurrentFixedPageWriter uninitialized
- FixedPageReader
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)