Пользовательский интерфейс Blazor не обновляется при вызове StateHasChanged - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть чрезвычайно простой пример из стандартного серверного шаблона Blazor, который показывает, что функция таймера не будет обновлять пользовательский интерфейс даже после StateHasChanged (); Вызов сделан.

Выходные данные журнала показывают срабатывание таймера, и если я подожду несколько секунд и нажму кнопку 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();
    }
}

1 Ответ

3 голосов
/ 24 апреля 2020

Вы используете приложение Blazor Server, верно? В этом случае вам следует вызвать метод StateHasChanged из метода InvokeAsyn c в ComponentBase следующим образом:

InvokeAsync(() => StateHasChanged());

Я полагаю, это происходит потому, что таймер выполняется в потоке, отличном от потока пользовательского интерфейса, для которого требуется синхронизация участвующих потоков. В Blazor WebAssembly такое поведение вряд ли произойдет, поскольку весь код выполняется в одном потоке пользовательского интерфейса.

Надеюсь, это поможет ...

...