-1

My code doesn't output any text, and then terminates after 5 seconds. Doing so in a non-async method does show output, but blocks other processes from running. Any thoughts and/or suggestions?

import asyncio, os, sys, time

def update(text):
    # Area of interest
    global print
    print("", flush=True)
    os.system("clear")
    print(text, flush=True)
    print("What is your selection? ", flush=True)

async def main():
    a = "a"
    while True:
        update(a)
        a += "c"
        time.sleep(0.05)
loop = asyncio.get_event_loop()
loop.create_task(main())
time.sleep(5)
9
  • don't interweave async and sync functions interdependently Commented Mar 14, 2023 at 18:30
  • 4
    What is the purpose of global print? Commented Mar 14, 2023 at 18:33
  • 1
    An async function needs to be awaited, otherwise it doesn’t do anything. Commented Mar 14, 2023 at 18:33
  • 1
    @JohnGordon, global print was my attempt at fixing this problem, and @deceze, how do I await an async function in the global scope? Commented Mar 14, 2023 at 18:35
  • 1
    main is async, which means other asynchronous could be "interleaved" with main, but main itself blocks any other function from being schedule until it is complete. You would want to use asyncio.wait instead of time.sleep at the very least. Commented Mar 14, 2023 at 18:47

1 Answer 1

2

your code in main itself never runs - you don´t call the event loop:

while asyncio.create_task will create a task and get it running "in the background" when you are already running asynchronous code, that never happens in this example:

Your modulelevel code gets a reference to an event loop, with get_event_loop, but uses create_task(main()) - that will create a task to run the main function, but you then never switch control to the asyncio event loop itself.

A more proper way isto have your synchronous code define things up to the point everything is ready, and then pass the control to the event loop so that it executes a "parent" task that may or not spawn others.

In recent Python versions, this is simply done with asyncio.run() - with no need to get an explicit reference to the loop prior to that. In older Python one would have to call get_event_loop() as you do, and would usually call loop.run_until_complete(main()).

There are other strange things in your code - including the use of os.system just to clear the screen - just print the ANSI sequence "\x1b[2J" on Unixes, or print("\n" * 70)` in any system.

The other thing is that you should use await asyncio.sleep(...) when using asyncio code, and never time.sleep

import asyncio
...

async def main():
    a = "a"
    while True:
        update(a)
        a += "c"
        await asyncio.sleep(0.05)

asyncio.run(main())

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.