Search code examples
c#blazor-server-side

Timer not working in Blazor Web Application


I have simple Blazor Web Application (Server Side, .NET 8, VS2022). Here main page:

@page "/"
@using System.Timers
@rendermode InteractiveServer

<p>@StatusMessage</p>

<button class="btn btn-primary" @onclick="StartHandler">Start</button>

@code {
    private void StartHandler()
    {
        Countdown = 100;
        timerCounter.Interval = 1000;
        timerCounter.Elapsed += TimerCounter_Elapsed;
        timerCounter.AutoReset = true;
        timerCounter.Start();
    }
    private void TimerCounter_Elapsed(object? sender, ElapsedEventArgs e)
    {        
        Countdown--;
        StatusMessage = $"{Countdown}";
    }

    private Timer timerCounter = new Timer();
    private int Countdown = 0;    
    private string StatusMessage = "";
}

It should start the timer on button click and show countdown on the page. But when I click the button nothing happened. On next clicks it shows count like 99 or 97. I don't understand what is going. Why the timer event doesn't fire? Thanks.

I tried countdown on button's click and it works. But I need the timer fires event.

Here is my App.razor file:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="/" />
    <link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
    <link rel="stylesheet" href="app.css" />
    <link rel="stylesheet" href="BlazorApp.styles.css" />
    <link rel="icon" type="image/png" href="favicon.png" />
    <HeadOutlet />
</head>

<body>
    <Routes />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

Solution

  • Add StateHasChanged. From the documentation: "Notifies the component that its state has changed. When applicable, this will cause the component to be re-rendered."

    private void TimerCounter_Elapsed(object? sender, ElapsedEventArgs e)
    {        
        Countdown--;
        StatusMessage = $"{Countdown}";
        StateHasChanged();        
    }