{"record":{"id":"a1758347a51b5ba0","repo":"dotnet/aspnetcore","slug":"the-current-thread-is-not-associated-with-the-disp","errorCode":null,"errorMessage":"The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.","messagePattern":"The current thread is not associated with the Dispatcher\\. Use InvokeAsync\\(\\) to switch execution to the Dispatcher when triggering rendering or component state\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Components/Components/src/Dispatcher.cs","lineNumber":32,"sourceCode":"    /// <summary>\n    /// Creates a default instance of <see cref=\"Dispatcher\"/>.\n    /// </summary>\n    /// <returns>A <see cref=\"Dispatcher\"/> instance.</returns>\n    public static Dispatcher CreateDefault() => new RendererSynchronizationContextDispatcher();\n\n    /// <summary>\n    /// Provides notifications of unhandled exceptions that occur within the dispatcher.\n    /// </summary>\n    internal event UnhandledExceptionEventHandler? UnhandledException;\n\n    /// <summary>\n    /// Validates that the currently executing code is running inside the dispatcher.\n    /// </summary>\n    public void AssertAccess()\n    {\n        if (!CheckAccess())\n        {\n            throw new InvalidOperationException(\n                \"The current thread is not associated with the Dispatcher. \" +\n                \"Use InvokeAsync() to switch execution to the Dispatcher when \" +\n                \"triggering rendering or component state.\");\n        }\n    }\n\n    /// <summary>\n    /// Returns a value that determines whether using the dispatcher to invoke a work item is required\n    /// from the current context.\n    /// </summary>\n    /// <returns><c>true</c> if invoking is required, otherwise <c>false</c>.</returns>\n    public abstract bool CheckAccess();\n\n    /// <summary>\n    /// Invokes the given <see cref=\"Action\"/> in the context of the associated <see cref=\"Renderer\"/>.\n    /// </summary>\n    /// <param name=\"workItem\">The action to execute.</param>\n    /// <returns>A <see cref=\"Task\"/> that will be completed when the action has finished executing.</returns>","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/Dispatcher.cs#L14-L50","documentation":"Blazor UI operations (rendering, StateHasChanged, navigation, component state changes) must execute on the Dispatcher's thread. Calling them from a background thread without marshaling throws InvalidOperationException. This protects single-threaded UI consistency.","triggerScenarios":"Triggering StateHasChanged, NavigationManager.NavigateTo, or component state mutations from Task.Run, a System.Threading.Timer callback, an async event, or any non-Dispatcher thread.","commonSituations":"Fire-and-forget async work, background timers, external event subscriptions (e.g. a hub or message bus), or long-running tasks that touch UI state on completion.","solutions":["Wrap UI-touching code in InvokeAsync(() => { ... }).","Use the component's Dispatcher explicitly: Dispatcher.InvokeAsync(...).","Avoid fire-and-forget async patterns; await or use Channel/observable patterns marshaled via InvokeAsync."],"exampleFix":"// before\n_ = Task.Run(() => { _data = Load(); StateHasChanged(); });\n// after\n_ = Task.Run(async () => {\n    var data = await Load();\n    await InvokeAsync(() => { _data = data; StateHasChanged(); });\n});","handlingStrategy":"validation","validationCode":"// Marshal UI work onto the Dispatcher before touching component state.\nif (!Dispatcher.CheckAccess())\n    await Dispatcher.InvokeAsync(() => UpdateState());\nelse\n    UpdateState();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always wrap UI-touching callbacks (timers, events, async) in InvokeAsync.","Avoid fire-and-forget _ = Task.Run(...) that touches component state.","Use Dispatcher.CheckAccess() defensively in cross-thread event handlers."],"tags":["blazor","dispatcher","threading","rendering"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}