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

问题描述:

我需要从服务结构中的分区中返回项目并将它们添加到列表中。结果来自异步方法。我试着了解发生了什么事情才能让它跑得更快。循环是否等到每个GetItems返回await为止,或者循环是否继续并为下一个分区启动一个新的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之前的所有内容。剩下的任务将被注册为延迟执行,并且可以立即执行并同步或在另一个线程上执行当前配置。

如果等待执行的任务异步执行,则实际的方法调用将返回,以便线程可以*执行其他任何操作,例如。刷新UI。然后这个重构的类似状态机的方法一次又一次被调用,轮询所等待的任务是否完成。一旦完成,状态将被切换,以便等待的行之后的代码将被执行,以此类推。

因此逻辑上是,循环一直等到结果存在,但实际上由于上述状态机类行为,线程并未被阻塞。

查看详细说明here

更新:

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

await Task.WhenAll(myTasks); 

await是“异步等待”。它暂停当前方法,并(异步)等待该操作完成后再继续。

请注意,方法已暂停,而不是线程。这就是使await成为“异步等待”而不是常规等待(“同步等待”)的原因。

欲了解更多信息,请参阅我的async/await intro

循环是否等待,直到每个GetItems返回await为止,或者循环是否继续并为下一个分区启动一个新的GetItems?

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