4

複数の非同期メソッドを呼び出す必要があり、それらの内部で別の非同期メソッドも呼び出す必要があります。実演させてください

private async void button1_Click(object sender, EventArgs e)
{
    for(int i = 0; i< 100; i++)
    {
        await Method1();
    }
}

public async Task Method1()
{
    await Task.Delay(3*1000);
    await Method2();
}

public async Task Method2()
{
    await Task.Delay(10*1000);
}

私の問題は、メソッド 2 の待機が開始された後にのみ for ステートメントが反復をアクティブにし、100 個のタスクを一度に作成することです。それ以外はすべて非同期で行われます。

4

2 に答える 2

8

あなたは「待つ」の意味について混乱していると思います。「待機」とは、「この処理を非同期で開始し、それが刻々と過ぎている間に、Windows メッセージ ループに戻り、UI が再描画を続けるようにメッセージの処理を続けることを意味します。非同期タスクが完了したら、私が待っていたコード」。

したがって、awaitそのようなループにいるときは、次のように言っています。

  • 最初の非同期ジョブを開始します...
  • 実行中は、メッセージ ループの処理を続けます。
  • 最初の非同期ジョブが完了すると...
  • 私たちが待っていたループで迎えに行きます。私たちはループを回って...
  • 2 番目の非同期ジョブを開始します...

それが望ましくない場合は、タスクを待機しないでください。同時に実行される 100 のタスクを開始する場合は、100 のタスクを開始し、それらのいずれも待機しません。クリック ハンドラに awaitがあるはなぜですか?

于 2013-04-24T21:05:58.767 に答える
3

for ループで作成した各タスクを -ing するのではなく、awaitすべてのタスクを開始したいだけです。前のタスクが完了するまで次のタスクのスケジューリングを遅らせたくないので、次のことはしないでくださいawait

private void button1_Click(object sender, EventArgs e)
{
    for(int i = 0; i< 100; i++)
    {
        var task = Method1();
    }
}

終わり。

すべてのタスクを並行して実行しながら、すべてのタスクが完了した後に何かを行うことが重要な場合Task.WhenAllは、他のすべてのタスクが完了したときに完了するタスクを生成することができます。

private async void button1_Click(object sender, EventArgs e)
{
    var tasks = new List<Task>();
    for(int i = 0; i< 100; i++)
    {
        tasks.Add(Method1());
    }
    await Task.WhenAll(tasks);
    textbox1.Text = "Done!"; //or whatever you want to do when they're all done
}
于 2013-04-24T21:05:28.593 に答える