ziptie.entity
ziptie.entity
CC#
Created by ziptie.entity on 6/24/2024 in #help
StateHasChanged not working in timers.
Hello, am trying to make a countdown timer to a specific date, it all works but for some reason even though I am calling StateHasChanged, it doesn't update, it only updates when I refresh the page. I also noticed that the dispose method (in the IDisposable interface) is called immediately after the page refreshes and the timer gets disposed instantly so it never has any time to run. .NET Version: 8.0.302
c#
@implements IDisposable

<span>@days, @hours, @minutes, @seconds</span>

@code {
private int days;
private int hours;
private int minutes;
private int seconds;

private Timer? timer;

protected override void OnInitialized()
{
StartTimer();
}

private void StartTimer()
{
DateTime targetDate = new DateTime(2024, 12, 31, 23, 59, 59);
UpdateCountdown(targetDate);

timer = new Timer(state =>
{
UpdateCountdown(targetDate);
InvokeAsync(StateHasChanged);
}, null, 0, 1000);
}

private void UpdateCountdown(DateTime targetDate)
{
var timeSpan = targetDate - DateTime.Now;

if (timeSpan.TotalSeconds < 0)
{
days = 0;
hours = 0;
minutes = 0;
seconds = 0;
timer?.Dispose();
}
else
{
days = timeSpan.Days;
hours = timeSpan.Hours;
minutes = timeSpan.Minutes;
seconds = timeSpan.Seconds;
}
}

public void Dispose()
{
timer?.Dispose();
}
}
c#
@implements IDisposable

<span>@days, @hours, @minutes, @seconds</span>

@code {
private int days;
private int hours;
private int minutes;
private int seconds;

private Timer? timer;

protected override void OnInitialized()
{
StartTimer();
}

private void StartTimer()
{
DateTime targetDate = new DateTime(2024, 12, 31, 23, 59, 59);
UpdateCountdown(targetDate);

timer = new Timer(state =>
{
UpdateCountdown(targetDate);
InvokeAsync(StateHasChanged);
}, null, 0, 1000);
}

private void UpdateCountdown(DateTime targetDate)
{
var timeSpan = targetDate - DateTime.Now;

if (timeSpan.TotalSeconds < 0)
{
days = 0;
hours = 0;
minutes = 0;
seconds = 0;
timer?.Dispose();
}
else
{
days = timeSpan.Days;
hours = timeSpan.Hours;
minutes = timeSpan.Minutes;
seconds = timeSpan.Seconds;
}
}

public void Dispose()
{
timer?.Dispose();
}
}
2 replies