私は非同期/待機が初めてで、タスクのリストを使用してオブジェクトのリストに対して操作を実行するためにそれをいじっています。Linq を使用して、オブジェクトのリストとタスクのリストの両方を生成しました。以下の例は少し不自然に見えますが、実際のコードを簡略化したものです。
示されているようにコードを実行すると、すべてのタスクが完了した後 (待機後)、オブジェクトの Now プロパティは更新されておらず、すべてのタスクのステータスが Running のままであることがわかりました。
.ToList<>() を介してオブジェクトとタスクの両方を実際のリストに変換することで Linq の遅延実行を排除することで、コードが期待どおりに機能することがわかりました (オブジェクトが入力され、タスクはすべて完了するまで実行されます)。
私は Linq の遅延実行に精通していますが、このコードで何が起こっているか (何が起こっていないか) に本当に混乱しています。私はおそらくasync/awaitで初心者の間違いを犯しています...それは何ですか?
private class Foo {
public DateTime Now { get; set; }
}
private void Button_Click( object sender, EventArgs e ) {
PopulateDates();
}
private async void PopulateDates() {
var ordinals = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, };
var foos = ordinals.Select( o => new Foo() ); //.ToList();
var tasks = foos.Select( f => PopulateDateAsync( f ) ); //.ToList();
await Task.WhenAll( tasks );
var firstNow = foos.ElementAt( 0 ).Now;
var firstTaskStatus = tasks.ElementAt( 0 ).Status;
}
private Task PopulateDateAsync( Foo foo ) {
return Task.Run( () => PopulateDate( foo ) );
}
private void PopulateDate( Foo foo ) {
Thread.Sleep( 2000 );
foo.Now = DateTime.Now;
}