如何在 Blazor WASM 上独立显示每个并行任务的执行情况?

How to display the execution of each parralel Task independenly on Blazor WASM?

描述:

有一个页面,应该显示来自两个独立异步操作的结果,例如 - REST 请求。

要显示第一个任务结果(通过 Blazor 生命周期方法执行请求),我们需要等待两个任务的执行,尽管第一个任务的数据已被服务获取。

问题:

如何在不等待第二个任务执行的情况下显示第一个任务的结果?

以这段代码为例。

第一个任务的结果只有在第二个任务执行后才会显示在页面上。

服务

public class TaskService : ITaskService
{
    public async Task<string> FirstTask()
    {
        const int timeOut = 500;
        await Task.Delay(timeOut);
        Console.WriteLine(timeOut);
        return nameof(FirstTask) + timeOut;
    }
    public async Task<string> SecondTask()
    {
        const int timeOut = 2500;
        await Task.Delay(timeOut);
        Console.WriteLine(timeOut);
        return nameof(SecondTask) + timeOut;
    }
}

页数

@page "/task-test"
@inject ITaskService _taskService

<h3>TaskTest</h3>

<p>First task: @_firstString</p>
<p>Second task: @_secondString</p>

@code {
    private string _firstString = "Init value";
    private string _secondString = "Init value";

    protected override async Task OnInitializedAsync()
    {
        var firstTask = _taskService.FirstTask();
        var secondTask = _taskService.SecondTask();

        await Task.WhenAll(firstTask, secondTask);
        _firstString = firstTask.Result;
        _secondString = secondTask.Result;
    }

}

FirstTask() 总是先完成时,您可以像@KirkWoll 评论的那样简化您的方法。看起来像这样:

protected override async Task OnInitializedAsync()
{
   _firstString = await _taskService.FirstTask();
   StateHasChanged();   
   _secondString = await _taskService.SecondTask();                 
}

我有一个独立等待两者的解决方案。虽然不是很漂亮。

protected override async Task OnInitializedAsync()
{
   var firstTask = async () => 
      { _firstString = await _taskService.FirstTask();
        StateHasChanged(); 
      };

   var secondTask = async () => 
     { _secondString = await _taskService.SecondTask(); 
       StateHasChanged(); 
     };
    
    await Task.WhenAll(firstTask(), secondTask());   // note the ()  
}

与 Henk 的回答类似,但语法不同以供比较。

protected override Task OnInitializedAsync()
{
    var firstTask = _taskService.FirstTask()
        .ContinueWith(t=> {
            _firstString=t.Result;
            StateHasChanged();
        });
    var secondTask = _taskService.SecondTask()
        .ContinueWith(t=> {
            _secondString = t.Result;
            StateHasChanged();
        });

    return Task.WhenAll(firstTask, secondTask);
}