从异步方法将项目添加到列表

Adding items to a list from asynchronous method

我需要 return Service Fabric 分区中的项目并将它们添加到列表中。结果来自异步方法。我试图了解正在发生的事情,以便更快地达到 运行。循环是等到每个 GetItems 都等待 returned,还是继续循环并为下一个分区启动新的 GetItems?

List<string> mylist = new List<string>();

foreach(var partition in partitions)
{
   var int64RangePartitionInformation = p.PartitionInformation as Int64RangePartitionInformation;
   if (int64RangePartitionInformation == null) continue;
   var minKey = int64RangePartitionInformation.LowKey;
   var assetclient = ServiceProxy.Create<IService>(serviceName, new ServicePartitionKey(minKey));
   var assets = await assetclient.GetItems(CancellationToken.None);
   mylist.AddRange(items)
}

await 关键字告诉编译器将您的方法重构为状态机。一旦您的 async 方法被调用,第一个 await 之前的所有内容都将被执行。其余任务将被注册为延迟执行,并且根据当前配置可以立即同步执行或在另一个线程上执行。

如果等待的任务是异步执行的,实际的方法调用 returns,因此线程可以自由地做任何其他事情,例如。刷新 UI。这个重构后的类似状态机的方法会被一次又一次地调用,轮询等待的任务是否完成。一旦完成,状态就会切换,等待行之后的代码将被执行,依此类推。

所以逻辑上是的,循环一直等到结果出现,但实际上线程并没有因为上面提到的类似状态机的行为而被阻塞。

查看详细说明here

更新:

如果可以从所有分区并行得到结果,就不要一一等待。相反,使用 Parallel.ForEach 或只是在 foreach 循环中填充一个 Task 集合,最后一步等待它们:

await Task.WhenAll(myTasks);

await 是一个 "asynchronous wait"。它暂停当前方法并(异步地)等待该操作完成后再继续。

注意暂停的是方法,而不是线程。这就是 await 成为 "asynchronous wait" 而不是常规等待 ("synchronous wait") 的原因。

有关详细信息,请参阅我的 async/await intro

Does the loop wait until await is returned for each GetItems, or does the loop continue and start a new GetItems for the next partition?

在每个 await,循环都在(异步)等待。因此,使用当前代码,一次只能调用一个服务,列表不必处理并发 AddRange 个调用。