我一直在使用 Blazor 和 C# 8.0 中的 IAsyncEnumerable 功能。是否可以在 Razor Pages 中使用 IAsyncEnumerable 和 wait 来逐步显示数据标记?
示例服务:
private static readonly string[] games = new[] { "Call of Duty", "Legend of Zelda", "Super Mario 64" };
public async IAsyncEnumerable<string> GetGames()
{
foreach (var game in games)
{
await Task.Delay(1000);
yield return game;
}
}
Razor 页面中的示例:
@await foreach(var game in GameService.GetGames())
{
<p>@game</p>
}
这会产生错误 CS4033:“await”运算符只能在异步方法中使用。考虑使用“async”修饰符标记此方法并将其返回类型更改为“Task”。
如果这可能的话有什么想法吗?
最佳答案
服务器端 Razor 允许您所描述的内容。 This video描述了 this Github repo 中的代码该示例展示了如何通过修改服务器端 Blazor 模板中的 ForecastService
示例来使用 IAsyncEnumerable。
修改服务本身很容易,并且实际上会产生更清晰的代码:
public async IAsyncEnumerable<WeatherForecast> GetForecastAsync(DateTime startDate)
{
var rng = new Random();
for(int i=0;i<5;i++)
{
await Task.Delay(200);
yield return new WeatherForecast
{
Date = startDate.AddDays(i),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
};
}
}
另一方面,Blazor 页面更为复杂。这不仅是循环必须在显示 HTML 之前完成,而且您不能在页面本身中使用 await foreach
因为它不是异步的。您只能在代码块中定义异步方法。
您可以做的是枚举 IAsyncEnumerable 并通知页面在每次更改后刷新自身。
渲染代码本身不需要更改:
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
OnInitializedAsync
需要在收到每个项目后调用 StateHasChanged()
:
List<WeatherForecast> forecasts;
protected override async Task OnInitializedAsync()
{
forecasts =new List<WeatherForecast>();
await foreach(var forecast in ForecastService.GetForecastAsync(DateTime.Now))
{
forecasts.Add(forecast);
this.StateHasChanged();
}
}
在问题的示例中,传入的游戏可以存储在列表中,保持渲染代码不变:
@foreach(var game in games)
{
<p>@game</p>
}
@code {
List<string> games;
protected override async Task OnInitializedAsync()
{
games =new List<games>();
await foreach(var game in GameService.GetGamesAsync())
{
games.Add(game);
this.StateHasChanged();
}
}
}
关于razor-pages - 您可以在 Razor 页面中使用 IAsyncEnumerable 来逐步显示标记吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57870709/