cefsharp/CefSharp · error · NotSupportedException
Can only be used when CEF is integrated into your WPF Messag
Error message
Can only be used when CEF is integrated into your WPF Message Loop (MultiThreadedMessageLoop = false).
What it means
DirectWritableBitmapRenderHandler renders CEF output to a WPF WriteableBitmap by hooking into CEF's on-screen rendering callbacks on the UI thread. This only works when CEF is configured with MultiThreadedMessageLoop = false (integrated message loop), because in multi-threaded mode the CEF UI thread is a separate thread and the render callbacks fire off-dispatcher.
Source
Thrown at CefSharp.Wpf/Rendering/DirectWritableBitmapRenderHandler.cs:37
/// <seealso cref="CefSharp.Wpf.IRenderHandler" />
public class DirectWritableBitmapRenderHandler : IRenderHandler
{
private readonly double dpiX;
private readonly double dpiY;
private readonly bool invalidateDirtyRect;
/// <summary>
/// Initializes a new instance of the <see cref="WritableBitmapRenderHandler"/> class.
/// </summary>
/// <param name="dpiX">The dpi x.</param>
/// <param name="dpiY">The dpi y.</param>
/// <param name="invalidateDirtyRect">if true then only the direct rectangle will be updated, otherwise the whole bitmap will be redrawn</param>
/// <param name="dispatcherPriority">priority at which the bitmap will be updated on the UI thread</param>
public DirectWritableBitmapRenderHandler(double dpiX, double dpiY, bool invalidateDirtyRect = true, DispatcherPriority dispatcherPriority = DispatcherPriority.Render)
{
if (!Cef.CurrentlyOnThread(CefThreadIds.TID_UI))
{
throw new NotSupportedException("Can only be used when CEF is integrated into your WPF Message Loop (MultiThreadedMessageLoop = false).");
}
this.dpiX = dpiX;
this.dpiY = dpiY;
this.invalidateDirtyRect = invalidateDirtyRect;
}
/// <inheritdoc/>
void IDisposable.Dispose()
{
}
/// <inheritdoc/>
void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, AcceleratedPaintInfo acceleratedPaintInfo)
{
throw new NotImplementedException();
}View on GitHub (pinned to 16bc6e0711)
Solutions
- Set CefSettings.MultiThreadedMessageLoop = false and CefExternalMessagePump = false in your CefSettings before Cef.Initialize.
- Use an IntegratedMessageLoopBrowserProcessHandler to drive the message loop from the WPF Dispatcher.
- Construct the render handler after CEF is initialized in integrated mode, on the UI thread.
Example fix
// before — default multi-threaded mode, constructor throws
var settings = new CefSettings();
Cef.Initialize(settings);
var renderHandler = new DirectWritableBitmapRenderHandler(96, 96);
// after — integrated message loop mode
var settings = new CefSettings
{
MultiThreadedMessageLoop = false,
ExternalMessagePump = false
};
settings.BrowserProcessHandler = new IntegratedMessageLoopBrowserProcessHandler(Dispatcher.CurrentDispatcher);
Cef.Initialize(settings);
var renderHandler = new DirectWritableBitmapRenderHandler(96, 96); Defensive patterns
Strategy: validation
Validate before calling
// Verify CEF is in integrated mode before constructing the handler
if (!Cef.CurrentlyOnThread(CefThreadIds.TID_UI))
{
throw new InvalidOperationException(
"DirectWritableBitmapRenderHandler requires MultiThreadedMessageLoop=false. " +
"Set it in CefSettings before Cef.Initialize.");
}
var renderHandler = new DirectWritableBitmapRenderHandler(dpiX, dpiY); Try / catch
try
{
var renderHandler = new DirectWritableBitmapRenderHandler(dpiX, dpiY);
}
catch (NotSupportedException ex) when (ex.Message.Contains("MultiThreadedMessageLoop"))
{
throw new InvalidOperationException(
"Switch to integrated message loop (MultiThreadedMessageLoop=false) to use this render handler.", ex);
} Prevention
- Set CefSettings.MultiThreadedMessageLoop = false and ExternalMessagePump = false before Cef.Initialize when using this handler.
- Provide an IntegratedMessageLoopBrowserProcessHandler in settings.BrowserProcessHandler.
- Construct render handlers after CEF init on the UI thread.
When it happens
Trigger: Constructing DirectWritableBitmapRenderHandler while Cef.CurrentlyOnThread(CefThreadIds.TID_UI) returns false — i.e., CEF is running in the default multi-threaded message loop mode, or the constructor is called from a non-UI thread before CEF is initialized in integrated mode.
Common situations: Forgetting to set CefSettings.MultiThreadedMessageLoop = false and CefExternalMessagePump = false before Cef.Initialize. Creating the render handler before CEF has been initialized so the thread check has no valid context.
Related errors
- Screenshot already in progress, you must wait for the previo
- Browser has not yet finished initializing or is being dispos
- Unable to take screenshot while browser is loading
- IBrowserHost is null
- Replace not implemented yet
AI-assisted analysis of cefsharp/CefSharp@16bc6e0711 (2026-08-13).
Data as JSON: /api/errors/6d53cde64b8d002f.
Report an issue: GitHub.