Peo*_*mer 1 .net c# async-await blazor-webassembly
我正在使用 Blazor Web 程序集项目的基本模板。我试图了解两种不同的方法似乎达到了相同的结果。
在我的第一次尝试中,我创建了一个方法,将新的 WeatherForecast 模型发布到我的 Web api 端点,然后从响应中将新创建的 WeatherForecast 添加到列表中。这是第一种方法:
private async void ValidSubmitHandler()
{
var response = await Http.PostAsJsonAsync<WeatherForecast>(Configuration["APIBaseUrl"] + "/WeatherForecast", newForecast);
var forecast = await response.Content.ReadFromJsonAsync<WeatherForecast>();
forecasts.Add(forecast);
}
Run Code Online (Sandbox Code Playgroud)
我期望 UI 能够使用新添加的预测进行更新,但尽管预测列表添加了新对象,但页面并未更新。我设置了一个断点,并观察到新的预测确实已添加到列表中,但只是 UI 没有呈现对列表状态的更改。
我听说你可以打电话
StateHasChanged()
Run Code Online (Sandbox Code Playgroud)
启动更改以呈现列表的新预测,目前还不错。在阅读了一些有关 StateHasChanged 的内容后,我似乎不应该经常使用它,而且它会显示出不良做法的迹象,因此我尝试了一位同事的建议,他说我需要将 Task 添加为返回类型而不是 void 到函数如下:
private async Task ValidSubmitHandler()
{
var response = await Http.PostAsJsonAsync<WeatherForecast>(Configuration["APIBaseUrl"] + "/WeatherForecast", newForecast);
var forecast = await response.Content.ReadFromJsonAsync<WeatherForecast>();
forecasts.Add(forecast);
}
Run Code Online (Sandbox Code Playgroud)
这确实允许 UI 接收更新,我只能假设 ValidSubmitHandler() 在新预测添加到列表之前退出。
如果我的方法没有等待异步操作的结果,有谁能解释为什么 StateHasChanged 似乎可以工作?
谢谢
StateHasChanged当事件处理程序完成时,Blazor 会自动调用。以下是来自 GitHub 的相关代码:
// https://github.com/dotnet/aspnetcore/blob/547de595414d6ebb9ddeaa4a231815449c9f3c60/src/Components/Components/src/ComponentBase.cs#L301
Task IHandleEvent.HandleEventAsync(EventCallbackWorkItem callback, object? arg)
{
var task = callback.InvokeAsync(arg);
var shouldAwaitTask = task.Status != TaskStatus.RanToCompletion &&
task.Status != TaskStatus.Canceled;
// After each event, we synchronously re-render (unless !ShouldRender())
// This just saves the developer the trouble of putting "StateHasChanged();"
// at the end of every event callback.
StateHasChanged();
return shouldAwaitTask ?
CallStateHasChangedOnAsyncCompletion(task) :
Task.CompletedTask;
}
Run Code Online (Sandbox Code Playgroud)
Blazor 等待事件处理程序返回。然后,它调用StateHasChanged. 如果返回的Task未完成,则等待任务并StateHasChanged再次调用。
在 的情况下async void,返回的任务始终已完成,因此它永远不会等待它并调用第二个StateHasChanged。在这种情况下,您需要手动调用它。但更好的方法是避免async void这几乎总是坏事。
我还写了一篇关于组件生命周期ASP.NET Core Blazor 组件生命周期的更深入的博客文章
| 归档时间: |
|
| 查看次数: |
794 次 |
| 最近记录: |