简体   繁体   中英

Passing Task as parameter to be invoked within loop in async method C#

I have the following code in 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;
    }
}

I can't for the life of me figure out why I get the following output:

Printing!

As opposed to "Printing." x3.

If I call Print1() directly within the loop I get the following output:

Printing!
Printing!
Printing!
Printing!

Which kind of makes sense but isn't what I want to do. Instead, I would like for Print1 (or whichever method is passed as task ) to be invoked iterations times.

Can someone help me understand what's up and down here? Thanks!

You are passing the result of calling Print1() to the method (a Task ). You aren't passing the method itself. So it's only called once at Print1() . When you await printer; , it's really just saying "yup, it happened" and moving on.

If you want to pass the method itself, so that it can be called inside PrintLoop , then you need to accept a Func<Task> (a method that returns a Task ).

Then you pass the method itself ( Print1 ) without calling it (not 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();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM