IncrementCounter (a ButtonClick handler) is the wrong thing to look at - it always runs on the SyncContext thread and can always use a plain StateHasChanged() without Invoke.
So lets look at a Timer event instead. The Threading.Timer class does not support async handlers so you run in a void Tick() { ... }
on an unspecified thread.
You do need InvokeAsync(StateHasChanged)
here. You could make the Tick method an async void
just to await the InvokeAsync but that gives of the wrong signals. Using InvokeAsync without await
is the lesser evil.
void Tick() // possibly threaded event handler
{
_counter++;
InvokeAsync(StateHasChanged); // fire-and-forget mode
}
But when you are in an async method and still need InvokeAsync, it is neater to await it, just because you can.
async Task SomeService()
{
_counter++;
await InvokeAsync(StateHasChanged);
}