首页 > 解决方案 > Blazor UI 未在 StateHasChanged 调用上更新

问题描述

我有一个来自标准 Blazor 服务器端模板的非常简单的示例,它显示即使在 StateHasChanged(); 之后计时器函数也不会更新 UI;已拨打电话。

日志输出显示定时器被触发,如果我等待几秒钟并单击 IncrementCount 按钮,计数值会跳转到计数器被定时器递增的次数。

非常好奇......任何帮助将不胜感激

亲切的问候,斯图尔特

@page "/counter"
@using System.Timers;

@using Microsoft.Extensions.Logging
@inject ILogger<Counter> Logger

<h1>Counter</h1>

<p>Current count: @(currentCount.ToString())</p>

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

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }

    public System.Timers.Timer timer;
    protected override async Task OnInitializedAsync()
    {
        timer = new Timer(1000);
        timer.Elapsed += this.OnTimedEvent;
        timer.AutoReset = true;
        timer.Enabled = true;
        timer.Start();
    }

    public void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Logger.LogInformation("Timer triggered");
        IncrementCount();
        StateHasChanged();
    }
}

标签: blazorblazor-server-side

解决方案


您正在运行 Blazor Server 应用程序,对吗?在这种情况下,您应该从 ComponentBase 的 InvokeAsync 方法中调用 StateHasChanged 方法,如下所示:

InvokeAsync(() => StateHasChanged());

我猜这是因为计时器在与 UI 线程不同的线程上执行,这需要同步所涉及的线程。在 Blazor WebAssembly 上,这种行为不太可能发生,因为所有代码都在同一个 UI 线程上执行。

希望这可以帮助...


推荐阅读