Run multiple await at the same time

牧云@^-^@ 提交于 2020-01-03 03:31:08

问题


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 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. 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 Tasks 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!