c# - Blazor:每次 for 循环旋转时组件不会更新

标签 c# .net razor blazor blazor-server-side

我目前正在开发 Blazor 项目并遇到一个错误。计划是只要 for 循环更新,就每秒更新一个组件。我的问题有点复杂,所以我在另一个项目中重现了这个错误:

进行计算的Calculate.cs 文件:

public class Calculate
{
    public void Calc(Index index)
    {
        for (int i = 0; i < 10; i++)
        {
            Thread.Sleep(1000);
            index.Update(i);
        }
    }
}

index.razor 文件:

<button class="btn btn-primary" @onclick="Test">Click me</button>

<p>Test number: @testNumber</p>

@code
{
    private int testNumber;
    Calculate c = new Calculate();

    public void Test()
    {
        c.Calc(this);   
    }
    public void Update(int i)
    {
        testNumber = i;
        Debug.WriteLine(i);
    }
}

测试后,调试控制台每秒都会打印应有的数字,从 0 到 9,但每当计算和 10 秒结束时,打开的 Blazor 显示屏仅打印 9。

最佳答案

只有当您可以使进程异步时,这才有效。

为此,请将 for 循环移至 Test() 方法,并将其设为任务返回方法。 Razor 代码可以保持原样。

public Task Test()
{
   for (int i = 0; i < 10; i++)
   {
       await Task.Run( _ =>  c.CalcSubTask(this));   

       Update(i);        
       StateHasChanged();
       await Task.Delay(1);
   }
}

并请注意,这仅在 Blazor/Server 中的性能可接受。在 Wasm 项目中,您只有 1 个线程,这会锁定您的 UI。


再考虑一下,您可以通过使 Calc 方法也异步并等待 Update() 方法来保持当前结构。然后 Update() 可以等待 Task.Delay(1)。

确保您拥有从 Test() 方法到 Calc 方法并返回到 Update() 的有效等待链。

更新方法看起来像

public async Task Update(int i)
{
    testNumber = i;
    Debug.WriteLine(i);
    await InvokeAsync(StatHasChanged);  // could be running on another Thread
    await Task.Delay(1);
}

关于c# - Blazor:每次 for 循环旋转时组件不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60799296/

相关文章:

c# - 如何在单独的线程中正确关闭异步套接字监听器?

c# - 是否可以在 C# 中将短时区字符串转换为 EST CET PST 到 TimeZoneInfo?

c# - Twitter Bootstrap 按钮在 chrome 上看起来很有趣,在 FF 上是灰色的

.net - 从构造函数调用方法是一种好习惯吗?

c# - 我可以检查操作是否是 View 中的子操作吗?

c# - NativeApplicationClient 和 OAuth2Authenticator 未解析

.net - 如何在类中引用 Session.Contents?

.net - 是否有任何 .net 等同于 Rails 固定装置?

c# - 在 Ajax.BeginForm MVC 4 场景中发送异常消息

c# - 如何在 HTML 中为 ASP.NET MVC 创建按钮?