1

我有一个看起来像这样的代码:

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"

所以现在它获取第一个列表,设置第一个TextBlock文本,然后获取第二个列表,设置第二个TextBlock文本,然后获取第三个列表并设置第三个TextBlock文本。但我希望所有 await 操作都同时运行,所以所有TextBlocks 都会或多或少地同时更新。或者可能不是同时 - 每个TextBlock都会​​随着相应的 await 方法完成而更新。无论如何,我想在这里实现的,是更快地得到结果。如果我一个一个地运行这些方法,它们会等到前一个方法完成,但是如果它们同时运行,第三种方法会更快地返回结果,对吗?所以我的问题是——这可能吗?如果是,那怎么办?

4

6 回答 6

5

我认为这就是你要找的:

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);
}

来源:http: //blog.stephencleary.com/2012/02/async-and-await.html

于 2016-04-28T07:14:57.467 回答
1

您可以尝试将工作转移到Tasks 的集合中并Task.WaitAll用于加入线程。

于 2016-04-28T07:11:02.667 回答
0

我希望所有等待操作都能同时运行,所以所有 TextBlocks 都会或多或少地同时更新。或者可能不是同时 - 每个 TextBlock 都会随着相应的 await 方法完成而更新。

然后定义几个新方法:

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";
}

然后同时调用它们:

var firstTask = GetFirstListFilesAndDisplayAsync();
var secondTask = GetSecondListFilesAndDisplayAsync();
var thirdTask = GetThirdListFilesAndDisplayAsync();

await Task.WhenAll(firstTask, secondTask, thirdTask);

firstList = await firstTask;
secondList = await secondTask;
thirdList = await thirdTask;
于 2016-04-28T12:57:09.297 回答
0

所以你不想对await块进行分组,你想指定它们完成时会发生什么。

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";
});

这种方式将是最快的方式,因为一旦Task完成,您textBlock.Text将被设置,并且他们不会等待前一个完成。

于 2016-04-28T07:21:29.953 回答
0

使用大卫的答案,或者就像将所有等待放在一起一样简单,然后像这样调用设置的文本值:

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"
于 2016-04-28T07:14:17.090 回答
-1

只需将您的等待对象的创建与它们的实际创建await分开:

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";

在第一个项目完成之前,这仍然不会显示任何结果,但确实允许并行进行。如果您确实想在单个函数中完成每个处理,那么它会更复杂WaitAny因为您必须在等待集合上,然后(手动)确定哪些已经完成,从集合中删除它们并循环直到全部完成。

于 2016-04-28T07:16:48.270 回答