Description:
There is a page, which should display results from two independent asynchronous operations, for example - REST requests.
To display the first task result (doing requests through Blazor lifecycle methods) we need to await execution of both tasks, despite the data from the first task being obtained by service.
Question:
How to display the result from the first task without awaiting the execution of the second task?
Consider this code as an example.
Results of the first task will be displayed on the page only after the execution of the second task.
Service
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
@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;
}
}
CodePudding user response:
When FirstTask() always finishes first, you can simplify your method as @KirkWoll commented. That looks like this:
protected override async Task OnInitializedAsync()
{
_firstString = await _taskService.FirstTask();
StateHasChanged();
_secondString = await _taskService.SecondTask();
}
I have a solution to wait for both, independently. It's not very pretty though.
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 ()
}
CodePudding user response:
Similar to Henk's answer, but different syntax for comparison.
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);
}
