dotnet/wpf · error · ObjectDisposedException

SR.InputProviderSiteDisposed

Error message

SR.InputProviderSiteDisposed

What it means

InputProviderSite.ReportInput throws ObjectDisposedException(SR.InputProviderSiteDisposed) when the site has already been disposed. An InputProviderSite is the bridge through which raw input providers (e.g. the per-monitor/per-hwnd input provider) deliver reports to the InputManager; once disposed, that channel is permanently invalid and input reports must stop.

Solutions

  1. Check site.IsDisposed before calling ReportInput and skip/report the event as stale.
  2. Ensure the input provider thread is stopped/disposed before or as part of tearing down the PresentationSource.
  3. Catch ObjectDisposedException around ReportInput in provider loops and exit the loop gracefully.

Example fix

// before
site.ReportInput(report);
// after
if (!site.IsDisposed)
    site.ReportInput(report);
Defensive patterns

Strategy: validation

Validate before calling

if (site.IsDisposed) return; // drop stale input report
site.ReportInput(report);

Type guard

static bool CanReport(InputProviderSite site) => site != null && !site.IsDisposed;

Try / catch

try { site.ReportInput(report); }
catch (ObjectDisposedException) { /* provider shutting down; stop loop */ break; }

Prevention

When it happens

Trigger: Calling ReportInput after InputProviderSite.Dispose() was invoked, e.g. a background input provider thread still pumping events after the PresentationSource/InputManager shut down.

Common situations: Shutting down a window or dispatcher while a custom or low-level input provider thread is still running; race between teardown and a queued input event; leaked provider references kept after HwndSource.Close.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/InputProviderSite.cs:80

            }
        }

        /// <summary>
        ///     Reports input to the input manager.
        /// </summary>
        /// <returns>
        ///     Whether or not any event generated as a consequence of this
        ///     event was handled.
        /// </returns>
        /// <remarks>
        ///  Do we really need this?  Make the "providers" call InputManager.ProcessInput themselves.
        ///  we currently need to map back to providers for other reasons.
        /// </remarks>
        public bool ReportInput(InputReport inputReport)
        {
            if(IsDisposed)
            {
                throw new ObjectDisposedException(SR.InputProviderSiteDisposed);
            }

            bool handled = false;

            InputReportEventArgs input = new InputReportEventArgs(null, inputReport)
            {
                RoutedEvent = InputManager.PreviewInputReportEvent
            };

            if (_inputManager is not null)
            {
                handled = _inputManager.ProcessInput(input);
            }

            return handled;
        }

        private bool _isDisposed;

View on GitHub (pinned to 81131a70a4)