cefsharp/CefSharp · error · ObjectDisposedException

Browser has been disposed

Error message

Browser has been disposed

What it means

ThrowExceptionIfDisposed checks the IsDisposed flag (backed by an interlocked dispose counter). Once the ChromiumWebBrowser has been disposed — through window close, explicit Dispose, or CEF shutdown — any further API call that calls ThrowExceptionIfDisposed throws ObjectDisposedException with the object name 'browser'.

Source

Thrown at CefSharp.Wpf/HwndHost/ChromiumWebBrowser.cs:1951

        /// </summary>
        /// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
        private void ThrowExceptionIfBrowserNotInitialized()
        {
            if (!InternalIsBrowserInitialized())
            {
                throw new Exception(BrowserNotInitializedExceptionErrorMessage);
            }
        }

        /// <summary>
        /// Throw exception if disposed.
        /// </summary>
        /// <exception cref="ObjectDisposedException">Thrown when a supplied object has been disposed.</exception>
        private void ThrowExceptionIfDisposed()
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException("browser", "Browser has been disposed");
            }
        }

        private int GetChromiumChildProcessId(string frameIdentifier)
        {
            try
            {
                var parts = frameIdentifier.Split('-');

                if (int.TryParse(parts[0], out var childProcessId))
                    return childProcessId;
            }
            catch
            {

            }

            return -1;

View on GitHub (pinned to 16bc6e0711)

Solutions

  1. Check IsDisposed before calling any browser API.
  2. Cancel pending async operations when the browser is disposed (use a CancellationToken).
  3. Unsubscribe from events and stop timers in the window Closing handler before the browser is disposed.

Example fix

// before — async op completes after close, throws
var shot = await browser.CaptureScreenshotAsync();

// after — guard against disposal
if (browser.IsDisposed) return;
var shot = await browser.CaptureScreenshotAsync();

// or use a cancellation token tied to disposal
cts.Token.ThrowIfCancellationRequested();
Defensive patterns

Strategy: validation

Validate before calling

if (browser.IsDisposed)
{
    return; // or throw a domain-specific exception
}
// safe to proceed
var shot = await browser.CaptureScreenshotAsync();

Try / catch

try
{
    var shot = await browser.CaptureScreenshotAsync();
}
catch (ObjectDisposedException) when (browser.IsDisposed)
{
    // Browser was disposed during async op — gracefully ignore or log
    Log.Info("Browser disposed before screenshot completed");
}

Prevention

When it happens

Trigger: Calling browser-dependent methods (CaptureScreenshotAsync, etc.) after Dispose has run, after the window/tab hosting the browser was closed, or after Cef.Shutdown.

Common situations: Async operations (e.g. an awaited screenshot or script evaluation) completing after the user closed the window. Event handlers firing during or after teardown. Timer-driven code that doesn't check disposal state.

Related errors


AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13). Data as JSON: /api/errors/5bc359419d7fb0b5. Report an issue: GitHub.