2016-09-14 7 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を使用するか、またはちょうどあなたのforeachループでTaskコレクションを移入し、最後に待っています:

await Task.WhenAll(myTasks); 
3

awaitは、「非同期待ち」です。現在のメソッドを一時停止し、(非同期に)その操作が完了するのを待ってから、続行します。

メソッドは、スレッドではなく、一時停止しています。これは、通常の待ち( "同期待機")の代わりにawaitを "非同期待機"にする理由です。

詳細については、async/await introを参照してください。

GetItemsごとにawaitが返されるまでループが待機するか、ループが続行されて次のパーティションの新しいGetItemsが開始されますか?

awaitでは、ループは(非同期に)待機しています。したがって、現在のコードでは、一度に1回のサービス呼び出しだけが実行されており、リストは並行してAddRangeコールを処理する必要はありません。

関連する問題