2016-09-14 55 views
2

我需要從服務結構中的分區中返回項目並將它們添加到列表中。結果來自異步方法。我試着瞭解發生了什麼事情才能讓它跑得更快。循環是否等到每個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) 
} 

回答

3

await關鍵字告訴編譯器將您的方法重構爲狀態機。一旦調用async方法,將執行第一個await之前的所有內容。剩下的任務將被註冊爲延遲執行,並且可以立即執行並同步或在另一個線程上執行當前配置。

如果等待執行的任務異步執行,則實際的方法調用將返回,以便線程可以自由執行其他任何操作,例如。刷新UI。然後這個重構的類似狀態機的方法一次又一次被調用,輪詢所等待的任務是否完成。一旦完成,狀態將被切換,以便等待的行之後的代碼將被執行,以此類推。

因此邏輯上是,循環一直等到結果存在,但實際上由於上述狀態機類行爲,線程並未被阻塞。

查看詳細說明here

更新:

如果結果可以並行的所有分區獲得,不要等待他們逐個。相反,在一個步驟中使用Parallel.ForEach或只是填充Task集合在你foreach循環,最後等待他們:

await Task.WhenAll(myTasks); 
3

await是「異步等待」。它暫停當前方法,並(異步)等待該操作完成後再繼續。

請注意,方法已暫停,而不是線程。這就是使await成爲「異步等待」而不是常規等待(「同步等待」)的原因。

欲瞭解更多信息,請參閱我的async/await intro

循環是否等待,直到每個GetItems返回await爲止,或者循環是否繼續併爲下一個分區啓動一個新的GetItems?

在每個await,循環是(異步)等待。因此,對於當前的代碼,一次只能調用一次服務,並且該列表不必處理併發的AddRange調用。