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
- Check IsDisposed before calling any browser API.
- Cancel pending async operations when the browser is disposed (use a CancellationToken).
- 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
- Check IsDisposed before every browser API call, especially in async and event-driven code.
- Cancel pending async operations when the browser is disposed.
- Unsubscribe event handlers and stop timers in the Closing/Unloaded handler.
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
- IBrowser
- Browser has already been created. BrowserSettings must be se
- Browser has already been created. RequestContext must be set
- Unexpected failure of calling CEF->GetZoomLevelAsync
- Cef.IsInitialized was false!.Check the log file for errors!.
AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13).
Data as JSON: /api/errors/5bc359419d7fb0b5.
Report an issue: GitHub.