Blazor 异常 - 当前线程未与 Dispatcher 关联。使用 InvokeAsync()

Clu*_*ang 14 .net-core asp.net-core blazor blazor-server-side

我的 Blazor 应用程序有这样的例外

System.InvalidOperationException: The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
   at Microsoft.AspNetCore.Components.Dispatcher.AssertAccess()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment)
   at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()
   at Microsoft.AspNetCore.Components.ComponentBase.Microsoft.AspNetCore.Components.IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, Object arg)
   at Microsoft.AspNetCore.Components.EventCallback`1.InvokeAsync(TValue arg)
   at MyApplication.Web.Shared.Application.ApplicationBarService.SearchFromUri(NavigationManager navigationManager) in /app/src/MyApplication.Web/Shared/Application/ApplicationBarService.cs:line 132
   at MyApplication.Web.Shared.Application.ApplicationBar.OnAfterRenderAsync(Boolean firstRender) in /app/src/MyApplication.Web/Shared/Application/ApplicationBar.razor:line 367
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
2020-09-01 10:32:06.818 +00:00 [ERR] Unhandled exception in circuit 'b625BJVxR9Sa5e1W6l6unK0G7RAkkLuM3kbvMggpJV0'.
System.InvalidOperationException: The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
   at Microsoft.AspNetCore.Components.Dispatcher.AssertAccess()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment)
   at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()
   at Microsoft.AspNetCore.Components.ComponentBase.Microsoft.AspNetCore.Components.IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, Object arg)
   at Microsoft.AspNetCore.Components.EventCallback`1.InvokeAsync(TValue arg)
   at MyApplication.Web.Shared.Application.ApplicationBarService.SearchFromUri(NavigationManager navigationManager) in /app/src/MyApplication.Web/Shared/Application/ApplicationBarService.cs:line 132
   at MyApplication.Web.Shared.Application.ApplicationBar.OnAfterRenderAsync(Boolean firstRender) in /app/src/MyApplication.Web/Shared/Application/ApplicationBar.razor:line 367
Run Code Online (Sandbox Code Playgroud)

它要求使用 InvokeAsync,但我已经进入了“OnAfterRenderAsync”!那么,为什么我会出现这样的问题呢?

在我的情况下,我有3个要素

  • ApplicationBarService(应用程序全局)
  • ApplicationBarComponent.razor
  • 页面 Index.razor

我怀疑什么

ApplicationBar 组件位于 Index.razor 页面内。这意味着 OnAfterRender 首先在 ApplicationBar 上调用,然后在 Index 上调用。

所以,这是调用堆栈/顺序:

  1. ApplicationBar.OnAfterRenderAsync ->
  2. ApplicationBarService.SearchFromUri ->(通过 EventCallback 调用完成)
  3. 索引.搜索(...)

一个问题是 Index.razor 尚未“准备好”(尚未调用 OnAfterRender)。在那里我无法进行任何 JS 调用:-(

也许我应该在所有“父母”准备好后进行此通话,但是如何?

一些代码

这是一个简单的事件

public EventCallback<SearchEventArgs> OnSearch;
Run Code Online (Sandbox Code Playgroud)

我这样称呼它:

await OnSearch.InvokeAsync(args);
Run Code Online (Sandbox Code Playgroud)

最后一个代码,在 Index.razor 上我有:

public async Task Search(SearchArgs args)
{
 base.InvokeAsync( ... );
}
Run Code Online (Sandbox Code Playgroud)

最后一个方法是由事件调用的方法,我还使用 base.InvokeAsync 来确保我在正确的线程中进行调用!但即使这样我还是有一些问题,我无法进行 JS 调用,因为 OnAfterRender 尚未被调用!

那么,您对这个问题有什么想法吗?

另外,我必须进行一些更改,以确保从相同的组件进行调用。如果你看一下代码:

  • 我从 OnAfterRender 调用,调用“静态”类,然后返回到同一组件。然后该组件尝试执行最后一次调用。
  • 在最后一次调用中,我使用 InvokeAsync 和 EventCallback (这也应该是 InvokeAsync)

但即使这样,它还是要求我调用 InvokeAsync (但它已经完成了)!!!

在此输入图像描述

tha*_*ker 15

如果没有看到所有代码,很难确定,但可能您需要围绕StateHasChanged类似的内容

InvokeAsync(StateHasChanged);
Run Code Online (Sandbox Code Playgroud)

Blazor 大学有很好的深入解释