finefoot
finefoot

Reputation: 11282

MicroPython uasyncio behaves differently on micro controller and regular Python: task just keeps running

This is my example:

try:
    import uasyncio as asyncio
except ImportError:
    import asyncio

async def count():
    i = 0
    while True:
        print(i)
        i += 1
        await asyncio.sleep(1)

async def main():
    asyncio.create_task(count())
    await asyncio.sleep(5)

asyncio.run(main())
asyncio.run(main())

In regular Python, I get:

0
1
2
3
4
0
1
2
3
4

However, MicroPython produces the following output:

0
1
2
3
4
0
5
1
6
2
7
3
8
4
9

So the first task doesn't stop but keeps running during the runtime of the second task.

Upvotes: 0

Views: 534

Answers (2)

finefoot
finefoot

Reputation: 11282

Apparently, this is currently expected behavior:

By default uasyncio retains state, as discussed here. Arguably in the interests of CPython compatibility it shouldn't, but on occasion this behaviour can be useful. Currently the user has the choice of whether to allow retained state.

Source: https://github.com/micropython/micropython/issues/7471

Therefore, a work-around would be to call asyncio.new_event_loop in between subsequent calls of asyncio.run:

try:
    import uasyncio as asyncio
except ImportError:
    import asyncio

async def count():
    i = 0
    while True:
        print(i)
        i += 1
        await asyncio.sleep(1)

async def main():
    asyncio.create_task(count())
    await asyncio.sleep(5)

asyncio.run(main())
asyncio.new_event_loop()
asyncio.run(main())

Upvotes: 0

MattyT
MattyT

Reputation: 6651

I believe this is a defect and I've logged issue #7471 to track it (there's also a workaround there). Thanks for reporting the problem with a clear, reproducible example!

Upvotes: 1

Related Questions