Confused about uasyncio.create_task() vs. await

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
dukeduck
Posts: 22
Joined: Thu Aug 29, 2019 2:06 pm

Confused about uasyncio.create_task() vs. await

Post by dukeduck » Tue Dec 01, 2020 1:55 pm

Hi,

I have read Peter's tutorial on Uasyncio V3, but am still a bit confused about the behaviors of `create_task()` and `await` and need some more education...

Regarding my confusion, I have a few sample codes as below.

Code: Select all

async def f1():
    for _ in range(10):
        print('f1')
        await uasyncio.sleep_ms(500)


async def f2():
    for _ in range(10):
        print('f2')
        await uasyncio.sleep_ms(1000)

async def m1():
    uasyncio.create_task(f1())
    await f2()

async def m2():
    t = uasyncio.create_task(f1())
    await t

async def m3():
    await f1()

async def m4():
    await f1()
    await f2()
1. When `m1()` was run, both `f1()` and `f2()` were run as expected, but when `m2()` was run, `f1()` was executed only once not twice, why is that?

2. I seemed to get same results from running `m2()` and `m3()`, what's the difference between the two?

3. For `m4()`, `f2()` was executed only after the completion of `f1()`, although there's `await uasyncio.sleep_ms(500)` inside `f1()`, the program performed as if it's synchronous. Is it because there's no task running in the background so the program just got executed line by line? Pls correct me if I'm misunderstood.

Thanks,
Kaiyuan

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Confused about uasyncio.create_task() vs. await

Post by pythoncoder » Tue Dec 01, 2020 6:35 pm

Code: Select all

async def m2():
    t = uasyncio.create_task(f1())
    await t

async def m3():
    await f1()
These are essentially identical. If you create a task and assign it to t, that operation occurs with immediate return. If you then await t, the f1 task runs to completion before m2 completes. You have only created a single instance of f1.

Code: Select all

async def m4():
    await f1()
    await f2()
This does what it says on the tin ;) It starts f1, but waits for it to complete before running f2. If you want them to run concurrently you need something like

Code: Select all

async def m4():
    t = uasyncio create_task(f1())  # f1 starts running
    await f2()  # Now you wait for f2
    await t  # In case f1 hasn't yet finished
There are other ways, especially if you want to wait for the completion of many tasks. See the gather primitive.
Peter Hinch
Index to my micropython libraries.

dukeduck
Posts: 22
Joined: Thu Aug 29, 2019 2:06 pm

Re: Confused about uasyncio.create_task() vs. await

Post by dukeduck » Wed Dec 02, 2020 9:49 am

Thanks so much Peter, very clear explaination!

Post Reply