Blazor, Updating or Refreshing the Display During a Method Call
Full source code available here.
This is a quick post showing 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 -
1@page "/"
2
3<h1>Updating the state of the page every second</h1>
4
5<p>Current count: @currentCount</p>
6
7<button class="btn btn-primary" @onclick="StartCounterAsync">Start counter</button>
8
9@code {
10 private int currentCount = 0;
11 private async Task StartCounterAsync()
12 {
13 for (int i = 1; i <= 10;)
14 {
15 await Task.Delay(1000);
16 currentCount = i++;
17 StateHasChanged();
18 await Task.Delay(1000);
19 currentCount = i++;
20 StateHasChanged();
21 }
22 }
23}
Once you know how to do it’s easy.
There is a scenario where using StateHasChanged()
won’t work and instead you’ll get an error like -
1Exception has occurred: CLR/System.InvalidOperationException
2An 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.'
3 at Microsoft.AspNetCore.Components.Dispatcher.AssertAccess()
4 at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment)
5 at Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged()
In this case use InvokeAsync(StateHasChanged);
instead and it should work.
Full source code available here.