Reputation: 29
Currently migrating blazor webassembly project to blazor server for performance improvements
In Razor page exisiting code where StateHasChanged() method calls is throwing below runtime exception in browser console: "Error: System.InvalidOperationException: The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state."
Tried below options but UI page is not getting updated accordingly
StateHasChanged() has been invoked in UI grid filters, button clicks, cascading dropdowns, etc
Please help in resolving this issue. In below code when user selects first dropdown (country) value, second dropdown (cities) data is fetched from backend service based on countryId
<InputSelect id="country" ValueExpression="@(() => country.Id)" Value="@country.Id"
ValueChanged="@((int? args) => { country.Id = args; GetCities(args); })"
class="form-control" style="appearance:auto;">
<option value="">-- Select Country --</option>
...
</InputSelect>
<InputSelect id="city" ValueExpression="@(() => city.Id)" Value="@city.Id"
ValueChanged="@((int? args) => { city.Id = args; FetchDistricts(args); })"
class="form-control" style="appearance:auto;">
<option value="">-- Select City --</option>
@foreach (var city in cities)
{
...
}
</InputSelect>
@code
{
public List<city> cities = new List<city>();
private async void GetCities(int? selectedvalue)
{
cities = await AppService.GetCitiesById(selectedvalue);
this.StateHasChanged();
}
}
Upvotes: 0
Views: 1355
Reputation: 30310
There are four common circumstances in which the error you have reported occurs:
Task.Run()
.ConfigureAwait(false)
, where the continuation contains a block of UI code.I don't see any of those here, so the problem is elsewhere. There are several candidates in the code you've shown us, but not provided details on: FetchDistricts
for instance.
Are you using ConfigureAwait(false)
anywhere in your code?
1, 2, and 3 are fixed by calling this.InvokeAsync(StateHasChanged)
.
4 is fixed by not doing it. Only veer from the straight Async
and Await
if you're an async expert and know what you're doing.
I suggest you refactor you code to move everything into GetCities
. You can then step through the code and see where the error occurs
// Must be task based to avoid UI problems
private async Task GetCities(int? selectedvalue)
{
// Not sure how you are dealing with nulls?
city.Id = selectedValue;
cities = await AppService.GetCitiesById(selectedvalue);
// Not needed
//this.StateHasChanged();
}
<InputSelect id="country" ValueExpression="@(() => country.Id)" Value="@country.Id"
ValueChanged=this.GetCities
class="form-control" style="appearance:auto;">
@if(country.Id is null)
{
<option value="" selected disabled>-- Select Country --</option>
}
// do foreach loop
...
</InputSelect>
Upvotes: 1