{"record":{"id":"a2493fcd54317d3a","repo":"cefsharp/CefSharp","slug":"cef-shutdown-has-already-been-called-it-s-no-long","errorCode":null,"errorMessage":"Cef.Shutdown has already been called, it's no longer possible to execute on the CEF UI Thread. Check CefThread.HasShutdown to guard against this execption","messagePattern":"Cef\\.Shutdown has already been called, it's no longer possible to execute on the CEF UI Thread\\. Check CefThread\\.HasShutdown to guard against this execption","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"critical","filePath":"CefSharp/Internals/CefThread.cs","lineNumber":88,"sourceCode":"\n        /// <summary>\n        /// returns true if Cef.Shutdown been called, otherwise false.\n        /// </summary>\n        public static bool HasShutdown { get; private set; }\n\n        /// <summary>\n        /// Execute the provided function on the CEF UI Thread\n        /// </summary>\n        /// <typeparam name=\"TResult\">result</typeparam>\n        /// <param name=\"function\">function</param>\n        /// <returns>Task{Result}</returns>\n        public static Task<TResult> ExecuteOnUiThread<TResult>(Func<TResult> function)\n        {\n            lock (LockObj)\n            {\n                if (HasShutdown)\n                {\n                    throw new Exception(\"Cef.Shutdown has already been called, it's no longer possible to execute on the CEF UI Thread. Check CefThread.HasShutdown to guard against this execption\");\n                }\n\n                var taskFactory = UiThreadTaskFactory;\n\n                if (taskFactory == null)\n                {\n                    //We don't have a task factory yet, so we'll queue for execution.\n                    return QueueForExcutionWhenUiThreadCreated(function);\n                }\n\n                return taskFactory.StartNew(function);\n            }\n        }\n\n        /// <summary>\n        /// Execute the provided action on the CEF UI Thread\n        /// </summary>\n        /// <param name=\"action\">action</param>","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/cefsharp/CefSharp/blob/16bc6e0711a4945be17e8bc4bc7ccf9469f3fdec/CefSharp/Internals/CefThread.cs#L70-L106","documentation":"Thrown by CefThread.ExecuteOnUiThread<TResult> when Cef.Shutdown has already run (HasShutdown is true). After shutdown the CEF UI thread and its TaskFactory are torn down (UiThreadTaskFactory is set to null and HasShutdown flipped), so no further work can be posted to it. The exception is raised synchronously inside the method under a lock so callers fail fast instead of deadlocking on a dead thread.","triggerScenarios":"Awaiting or invoking any CefSharp API that internally calls CefThread.ExecuteOnUiThread (e.g. certain async extension methods, EvaluateScriptAsync continuations, cookie/JS repository operations on the UI thread) after Cef.Shutdown has been called during app shutdown or browser disposal.","commonSituations":"Application shutdown ordering: Cef.Shutdown() runs while background tasks, timers, or disposed-browser callbacks still try to touch the UI thread; a second browser instance created after shutdown; deferred Task continuations that outlive the CEF lifetime; calling browser operations during Application.Exit or Form.Closed before Cef.Shutdown but racing the shutdown.","solutions":["Cancel/await all outstanding async operations before calling Cef.Shutdown().","Guard calls with if (!CefThread.HasShutdown) before invoking UI-thread-dependent APIs.","Fix shutdown ordering: dispose all ChromiumWebBrowser instances and complete pending work first, then call Cef.Shutdown() exactly once at the very end.","Ensure Cef.Shutdown is not called from a finalizer or an unexpected code path that races live work."],"exampleFix":"// before\nCef.Shutdown();\nvar result = await browser.EvaluateScriptAsync(\"someScript()\");\n\n// after\nvar result = await browser.EvaluateScriptAsync(\"someScript()\");\nbrowser.Dispose();\nCef.Shutdown();\n// or guard at call sites:\nif (!CefThread.HasShutdown) { /* post work */ }","handlingStrategy":"validation","validationCode":"if (!CefThread.HasShutdown)\n{\n    return CefThread.ExecuteOnUiThread(() => DoWork());\n}\nreturn Task.FromResult(default(TResult));","typeGuard":"static bool CanUseUiThread => !CefThread.HasShutdown;","tryCatchPattern":"try\n{\n    return await CefThread.ExecuteOnUiThread(() => DoWork());\n}\ncatch (Exception ex) when (CefThread.HasShutdown)\n{\n    // Context already torn down; nothing to post. Log and return default.\n    return default;\n}","preventionTips":["Drain/await all UI-thread tasks before Cef.Shutdown().","Guard every UI-thread-dependent call with CefThread.HasShutdown.","Order teardown: dispose browsers, complete work, then call Cef.Shutdown() exactly once last."],"tags":["lifecycle","shutdown","threading","ui-thread","cefsharp"],"backgroundTag":null,"analyzedSha":"16bc6e0711a4945be17e8bc4bc7ccf9469f3fdec","analyzedAt":"2026-08-13T19:57:05.828Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}