编辑:澄清一下,这是在Blazor服务器应用程序
我对InvokeAsync的正确使用和更新UI感到困惑。文档中有几个用法,但没有真正解释等待或不等待的原因。我也看到过一些相互矛盾的帖子,但没有多少证据支持他们的推理。
使所有方法异步等待InvokeAsync(StateHasChanged)似乎是错误的,我在某处读到引入InvokeAsync的原因是为了防止到处需要异步代码。但是在什么情况下我想等待它呢?
等待:
https://learn.microsoft.com/en us/aspnet/core/blazor/components/?view=aspnetcore - 5.0, viewFallbackFrom = aspnetcore - 3.0 # invoke-component-methods-externally-to-update-state
non-await丢弃:
https://learn.microsoft.com/en us/aspnet/core/blazor/components/rendering?view=aspnetcore - 5.0
下面是我看到的一些不同用法的例子,如果有人能解释一下或分享一下它们之间的区别,那就太好了(谢谢!)
public void IncrementCounter()
{
_counter++;
InvokeAsync(StateHasChanged);
}
public void IncrementCounter()
{
InvokeAsync(() =>
{
_counter++;
StateHasChanged);
}
}
public async Task IncrementCounter()
{
_counter++;
await InvokeAsync(StateHasChanged);
}
public async Task IncrementCounter()
{
await InvokeAsync(() =>
{
_counter++;
StateHasChanged();
});
}
IncrementCounter(一个ButtonClick处理程序)是错误的-它总是在SyncContext线程上运行,并且总是可以使用普通的StateHasChanged()而不需要调用。
让我们来看看Timer事件。线程。定时器类不支持异步处理程序,所以你在void Tick() { ... }
中运行在一个未指定的线程上。
这里确实需要InvokeAsync(StateHasChanged)
。您可以使Tick方法一个async void
只是等待InvokeAsync,但这给出了错误的信号。使用没有await
的InvokeAsync是较小的害处。
void Tick() // possibly threaded event handler
{
_counter++;
InvokeAsync(StateHasChanged); // fire-and-forget mode
}
但是当你在异步方法中并且仍然需要InvokeAsync时,等待它会更简洁,因为你可以。
async Task SomeService()
{
_counter++;
await InvokeAsync(StateHasChanged);
}