使用 IJSRuntime Blazor 时的屏幕渲染问题

GT *_*Kim 4 blazor asp.net-core-signalr asp.net-core-3.1 blazor-jsinterop

首先,我对我的英语水平感到非常抱歉。

我目前正在通过 dotnet core 3.1 blazor 开发一个 Web 项目。

如下面的源代码所示,我使用 IJSRuntime 调用需要很长时间的 Javascript 函数。

[Inject]
IJSRuntime JSRuntime { get; set; }
private async Task BtnDisplay()
    await JSRuntime.InvokeVoidAsync("RefreshWebJS", Data);
}
Run Code Online (Sandbox Code Playgroud)

Javascript 函数需要很长时间,因此我添加了下面的源代码来添加微调器。

private async Task BtnDisplay()
{
    showLoadingImg = true; // add
    await JSRuntime.InvokeVoidAsync("RefreshWebJS", Data);
    showLoadingImg = false;
}
Run Code Online (Sandbox Code Playgroud)

Spinner 在 razor 页面上定义如下:

@if (showLoadingImg == true)
{
    <div style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; text-align: center;">
    <img src="/images/LoadingImg.gif" style="position: absolute; top: 50%; left: 50%;" />
    </div>
}
Run Code Online (Sandbox Code Playgroud)

“StateHasChanged()”或“await InvokeAsync(() => StateHasChanged())”也不起作用。

当我使用 Task 而不是 JSRuntime 时,它​​工作得很好。

await Task.Delay(1000); 
Run Code Online (Sandbox Code Playgroud)

为什么当我使用 JSRuntime.InvokeVoidAsync 时它不起作用?

谢谢您,也很抱歉阅读困难的英语。

Mis*_*goo 5

private async Task BtnDisplay()
{
    showLoadingImg = true; // add
    await Task.Delay(1);
    await JSRuntime.InvokeVoidAsync("RefreshWebJS", Data);
    showLoadingImg = false;
}
Run Code Online (Sandbox Code Playgroud)

Task当您await完成异步任务中的第一个任务时,Blazor 会自动重新渲染。

因此,如果第一个Task是您长时间运行的进程,则在完成之前它不会重新渲染。

添加await Task.Delay(1)是一种允许在长时间运行的进程之前进行渲染的简单方法。

进一步阅读: https: //github.com/dotnet/aspnetcore/issues/22159

这是 Blazor 工作方式的已知功能,Blazor 的创建者也在该线程中推荐了这种方法(尽管他更喜欢await Task.Yield()- 我总是忘记使用!)