cefsharp/CefSharp · error · Exception
Screenshot already in progress, you must wait for the previo
Error message
Screenshot already in progress, you must wait for the previous screenshot to complete
What it means
Thrown by the example ChromiumWebBrowserWithScreenshotSupport.TakeScreenshot when a previous screenshot Task is still Running (tracked via a TaskCompletionSource whose Task.Status == TaskStatus.Running). The control resizes the off-screen browser to capture a frame and cannot run two captures concurrently without corrupting the frame buffer and state, so it serializes screenshots.
Source
Thrown at CefSharp.Wpf.Example/Controls/ChromiumWebBrowserWithScreenshotSupport.cs:51
private volatile bool isTakingScreenshot = false;
private Size? screenshotSize;
private int oldFrameRate;
private int ignoreFrames = 0;
private TaskCompletionSource<InteropBitmap> screenshotTaskCompletionSource;
private CancellationTokenRegistration? cancellationTokenRegistration;
public ICommand ScreenshotCommand { get; set; }
public ChromiumWebBrowserWithScreenshotSupport() : base()
{
ScreenshotCommand = new RelayCommand(TakeScreenshot);
}
public Task<InteropBitmap> TakeScreenshot(Size screenshotSize, int? frameRate = 1, int? ignoreFrames = 0, CancellationToken? cancellationToken = null)
{
if (screenshotTaskCompletionSource != null && screenshotTaskCompletionSource.Task.Status == TaskStatus.Running)
{
throw new Exception("Screenshot already in progress, you must wait for the previous screenshot to complete");
}
if (IsBrowserInitialized == false)
{
throw new Exception("Browser has not yet finished initializing or is being disposed");
}
if (IsLoading)
{
throw new Exception("Unable to take screenshot while browser is loading");
}
var browserHost = this.GetBrowserHost();
if (browserHost == null)
{
throw new Exception("IBrowserHost is null");
}View on GitHub (pinned to 16bc6e0711)
Solutions
- Await the Task returned by the previous TakeScreenshot call before starting another.
- Track an `isCapturing` flag (or use the TCS) and ignore/disable the trigger while a capture is in flight.
- Debounce the ScreenshotCommand or button so rapid clicks do not stack calls.
- Serialize captures in a queue if you genuinely need back-to-back screenshots.
Example fix
// before var shot1 = browser.TakeScreenshot(size); var shot2 = browser.TakeScreenshot(size); // throws: previous still running // after var shot1 = await browser.TakeScreenshot(size); var shot2 = await browser.TakeScreenshot(size);
Defensive patterns
Strategy: validation
Validate before calling
if (screenshotTcs == null || screenshotTcs.Task.Status != TaskStatus.Running)
{
screenshotTcs = browser.TakeScreenshot(size);
} Prevention
- Always await the previous TakeScreenshot Task before starting another.
- Debounce the screenshot trigger / command.
- Track an isCapturing flag and disable the UI button while in flight.
When it happens
Trigger: Invoking TakeScreenshot again before the prior returned Task has completed; firing the ScreenshotCommand rapidly; calling from a loop without awaiting.
Common situations: A UI button with no debounce; chaining screenshots without await; a timer firing faster than capture completes.
Related errors
- Browser has not yet finished initializing or is being dispos
- Unable to take screenshot while browser is loading
- IBrowserHost is null
- {nameof(viewPort)}.{nameof(viewPort.Scale)} must be greater
- Replace not implemented yet
AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13).
Data as JSON: /api/errors/89f48d2908cefd21.
Report an issue: GitHub.