Blazor StreamRendering 已无法在示例项目中工作

问题描述 投票:0回答:1

我是 Blazor 新手,从 YouTube 教程开始。 因此,我在 VS 2022(最新版本)和 .NET Runtime 8.0.6 中创建了 Blazor Web App 项目。我在项目中包含了示例代码(天气应用程序),并让它运行而不更改任何示例代码。

BlazorWebApp

SampleWebsite

当我打开“天气”选项卡时,它应该立即打开天气页面,显示“正在加载...”500 毫秒,然后显示一个包含一些温度的表格。在我的例子中,它会等待 500 毫秒,然后打开天气选项卡并立即显示表格。

这是 blazor 示例文件的代码:

@page "/weather"
@attribute [StreamRendering]

<PageTitle>Weather</PageTitle>

<h1>Weather</h1>

<p>This component demonstrates showing data.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <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>
}

@code {
    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        // Simulate asynchronous loading to demonstrate streaming rendering
        await Task.Delay(2000);

        var startDate = DateOnly.FromDateTime(DateTime.Now);
        var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
        forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = startDate.AddDays(index),
            TemperatureC = Random.Shared.Next(-20, 55),
            Summary = summaries[Random.Shared.Next(summaries.Length)]
        }).ToArray();
    }

    private class WeatherForecast
    {
        public DateOnly Date { get; set; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
}

因此 @attribute [StreamRendering] 不起作用,因为它不会在服务器端异步运行 OnInitializedAsync() 方法。

还有一篇 GitHub 帖子显示了完全相同的问题 https://github.com/dotnet/aspnetcore/issues/52323。 这个与 IIS 压缩问题更相关,不包含适合我的解决方案。就我而言,它也不适用于 http、https 或 IIS。 我使用哪个浏览器也没关系,而且它在我同事的电脑上也无法运行。

在开始使用 Blazor 之前我就已经很沮丧了......

c# visual-studio asp.net-core blazor
1个回答
0
投票

经过我的调查,我发现示例项目中

await Task.Delay(2000);
的用法是错误的。这意味着应用程序将保持2秒,然后数据将显示在页面中。

所以我自定义了

GenerateForecastsAsync
方法来每2秒生成一次数据。这是完整的代码,它对我有用。

@page "/weather"
@attribute [StreamRendering]

<PageTitle>Weather</PageTitle>

<h1>Weather</h1>

<p>This component demonstrates showing data.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <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>
}

@code {
    private List<WeatherForecast> forecasts = [];

    protected override async Task OnInitializedAsync()
    {
        

        var startDate = DateOnly.FromDateTime(DateTime.Now);
         var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
        // forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast
        // {
        //     Date = startDate.AddDays(index),
        //     TemperatureC = Random.Shared.Next(-20, 55),
        //     Summary = summaries[Random.Shared.Next(summaries.Length)]
        // }).ToArray();
        await foreach (var weather in GenerateForecastsAsync(startDate, summaries, 50000))
        {
            forecasts.Add(weather);
            StateHasChanged();
        }
    }
    private async IAsyncEnumerable<WeatherForecast> GenerateForecastsAsync(DateOnly startDate, string[] summaries, int count)
    {
        for (int i = 0; i < count; i++)
        {
            yield return new WeatherForecast
                {
                    Date = startDate.AddDays(i),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = summaries[Random.Shared.Next(summaries.Length)]
                };

            await Task.Delay(2000); // Optional throttling to prevent overwhelming UI
        }
    }

    private class WeatherForecast
    {
        public DateOnly Date { get; set; }
        public int TemperatureC { get; set; }
        public string? Summary { get; set; }
        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.