Передача Task в качестве параметра, который будет вызван в цикле в асинхронном методе C # - PullRequest
2 голосов
/ 11 октября 2019

У меня есть следующий код в LINQPad:

async Task Main()
{
    await PrintLoop(Print1());
}

async Task Print1()
{
    Debug.WriteLine("Printing!");
}

//Print 2
//Print 3
//etc.

async Task PrintLoop(Task printer, int iterations = 3)
{
    for (int i = 0; i < iterations; i++)
    {
        await printer;
    }
}

Я не могу на всю жизнь понять, почему я получаю следующий вывод:

Printing!

В отличие от«Печать!»x3.

Если я вызываю Print1() непосредственно в цикле, я получаю следующий вывод:

Printing!
Printing!
Printing!
Printing!

Какой тип имеет смысл, но не тот, который я хочу сделать. Вместо этого я хотел бы, чтобы Print1 (или какой-либо метод, передаваемый как task), вызывался iterations раз.

Может ли кто-нибудь помочь мне понять, что здесь происходит вверх и вниз? Спасибо!

1 Ответ

3 голосов
/ 11 октября 2019

Вы передаете результат вызова Print1() методу (a Task). Вы не передаете сам метод. Так что он вызывается только один раз в Print1(). Когда вы await printer;, на самом деле это просто говорит: «Да, это случилось» и идет дальше.

Если вы хотите передать сам метод, чтобы его можно было вызывать внутри PrintLoop, тогда вам нужнопринять Func<Task> (метод, который возвращает Task).

Затем вы передаете сам метод (Print1), не вызывая его (не Print1())

async Task Main()
{
    await PrintLoop(Print1); //not Print1()
}

async Task Print1()
{
    Debug.WriteLine("Printing!");
}

async Task PrintLoop(Func<Task> printer, int iterations = 3)
{
    for (int i = 0; i < iterations; i++)
    {
        await printer();
    }
}
...