Full source code available BlazorUpdatingUIEverySecondWasm.
This is a quick post to show how to show how to refresh or update components on a Blazor page asynchronously, for example in response to a task or tasks completing.
In this example I have a button that calls a method, inside the method I have for loop, inside each iteration of the for loop, I increment the counter twice, delay twice, and update the display twice using a call to StateHasChanged()
.
Here is the code –
@page "/" <h1>Updating the state of the page every second</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="StartCounterAsync">Start counter</button> @code { private int currentCount = 0; private async Task StartCounterAsync() { for (int i = 1; i <= 10;) { await Task.Delay(1000); currentCount = i++; StateHasChanged(); await Task.Delay(1000); currentCount = i++; StateHasChanged(); } } }
Once you know how to do it’s easy.
There is scenario where using StateHasChanged()
won’t work and instead you’ll get an error like –
Exception has occurred: CLR/System.InvalidOperationException An exception of type 'System.InvalidOperationException' occurred in Microsoft.AspNetCore.Components.dll but was not handled in user code: 'The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.' at Microsoft.AspNetCore.Components.Dispatcher.AssertAccess() at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment) at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()
In this case use InvokeAsync(StateHasChanged);
instead and it should work.
Full source code available BlazorUpdatingUIEverySecondWasm.