问题
I have a code that looks something like this:
firstList = await GetFirstListFilesAsync();
textBlock1.Text = "found " + firstList.Count + " first list's results";
secondList = await GetSecondListFilesAsync();
textBlock2.Text = "found " + secondList.Count + " second list's results";
thirdList = await GetThirdListFilesAsync();
textBlock3.Text = "found " + thirdList.Count + " third list's results"
So now it gets first list, sets first TextBlock
text, then it gets second list, sets second TextBlock
text and then gets third list and sets third TextBlock
text. But I would like that all await operations would run simultaneously, so all TextBlock
s would update more or less at the same time. Or maybe not at the same time - each TextBlock
would update as the corresponding await method finishes. Anyway, what I want to achieve here, is to get results faster. if I run those methods one by one, they wait until the previous is finished, but if they would run all at the same time, third method would return the result faster, right? So my question is - is that possible? And if yes, then how?
回答1:
I think this is what you are looking for:
var tasks = new Task<MyMethodReturnObject>[3];
tasks[0] = GetFirstListFilesAsync();
tasks[1] = GetSecondListFilesAsync();
tasks[2] = GetThirdListFilesAsync();
// At this point, all three tasks are running at the same time.
// Now, we await them all.
await Task.WhenAll(tasks);
// Get an individual result, where result is MyMethodReturnObject
var myText = tasks[0].Result;
// Loop through results
var results = tasks.Select(o => o.Result).ToList();
foreach (var result in results)
{
Console.Write(result);
}
Source: http://blog.stephencleary.com/2012/02/async-and-await.html
回答2:
You can try and shift the work into a collection of Task
s and the use Task.WaitAll to join the threads.
回答3:
Use david's answer or just as simple as putting all the waits together then call the set text value like this :
firstList = await GetFirstListFilesAsync();
secondList = await GetSecondListFilesAsync();
thirdList = await GetThirdListFilesAsync();
textBlock1.Text = "found " + firstList.Count + " first list's results";
textBlock2.Text = "found " + secondList.Count + " second list's results";
textBlock3.Text = "found " + thirdList.Count + " third list's results"
回答4:
So you don't want to group the await
blocks, you want to specify what happens when they complete.
GetFirstListFilesAsync().ContinueWith(task => {
textBlock1.Text = "found " + task.Result.Count + " first list's results";
});
GetSecondListFilesAsync().ContinueWith(task => {
textBlock2.Text = "found " + task.Result.Count + " second list's results";
});
GetThirdListFilesAsync().ContinueWith(task => {
textBlock3.Text = "found " + task.Result.Count + " third list's results";
});
This way will be the fastest way to do this, because as soon as the Task
completes, your textBlock.Text
will be set, and they will not wait on the previous one to complete.
回答5:
I would like that all await operations would run simultaneously, so all TextBlocks would update more or less at the same time. Or maybe not at the same time - each TextBlock would update as the corresponding await method finishes.
Then define a few new methods:
private async Task<TFirst> GetFirstListFilesAndDisplayAsync()
{
var firstList = await GetFirstListFilesAsync();
textBlock1.Text = "found " + firstList.Count + " first list's results";
}
private async Task<TSecond> GetSecondListFilesAndDisplayAsync()
{
var secondList = await GetSecondListFilesAsync();
textBlock2.Text = "found " + secondList.Count + " second list's results";
}
private async Task<TThird> GetThirdListFilesAndDisplayAsync()
{
var thirdList = await GetThirdListFilesAsync();
textBlock3.Text = "found " + thirdList.Count + " third list's results";
}
And then call them all concurrently:
var firstTask = GetFirstListFilesAndDisplayAsync();
var secondTask = GetSecondListFilesAndDisplayAsync();
var thirdTask = GetThirdListFilesAndDisplayAsync();
await Task.WhenAll(firstTask, secondTask, thirdTask);
firstList = await firstTask;
secondList = await secondTask;
thirdList = await thirdTask;
回答6:
Just seperate the creation of your awaitables from the actual await
on them:
var firstWait = GetFirstListFilesAsync();
var secondWait = GetSecondListFilesAsync();
var thirdWait = GetThirdListFilesAsync();
firstList = await firstWait;
textBlock1.Text = "found " + firstList.Count + " first list's results";
secondList = await secondWait ;
textBlock2.Text = "found " + secondList.Count + " second list's results";
thirdList = await thirdWait ;
textBlock3.Text = "found " + thirdList.Count + " third list's results";
This still won't show any results until the first item has completed, but does allow progress to be made in parallel. It's more complex if you do want to deal with each one as it completes inside a single function, since you then have to WaitAny
on the collection of awaitables, then determine (manually) which one(s) have completed, remove those from the collection and loop around until all have finished.
来源:https://stackoverflow.com/questions/36907549/run-multiple-await-at-the-same-time