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

  1. Set CefSettings.MultiThreadedMessageLoop = false and CefExternalMessagePump = false in your CefSettings before Cef.Initialize.
  2. Use an IntegratedMessageLoopBrowserProcessHandler to drive the message loop from the WPF Dispatcher.
  3. 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

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


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