EDM115
EDM115

Reputation: 73

Asyncio : how to run one task in another one concurrently?

I have two functions, both are async and they run outside a function thanks to asyncio
However, the second function is inside the first one, and it's blocking the execution of the first :
(note that this needs to be compatible with most used Python versions, from 3.8 to latest one)

async def func_2():
  # basically does a request to a website and returns the status code

async def func_1():
  tab = ["el0", "el1", ..., "el10"]  
  for i in range(len(tab)):
    sys.stdout.write("\r[∆] Progress: " + tab[i % len(tab)])
    sys.stdout.flush()
    if i == 1:
      result = await func_2()
    await asyncio.sleep(0.4)
  return result

while True: 
  func = asyncio.get_event_loop()
  func_coroutine = func_1()
  result = anim.run_until_complete(func_coroutine)
  if result == 200:
    print("Up")
  else:
    print("Down")

The func_1() is just here to make the user wait, but the func_2() does the real job, and takes way more time than 0.4 seconds 🥲

So my question is : It is possible to make the func_1() continuing to run (and show stuff to the user) while the func_2() is running ?

Upvotes: 1

Views: 1446

Answers (1)

Paul Cornelius
Paul Cornelius

Reputation: 11009

To do what you want, convert func_2 into a task. Then loop inside func_1 until func_2 is finished. The two tasks will play together, giving an appearance of concurrency.

I replaced your func_2 with a simple asyncio.sleep. I used the print function for the status messages instead of stdout.write. I print the final result, showing that the data from func_2 is accessible by the task's result() method.

I realize that your application will do something useful, so this little script is just an example framework.

Tested with Python 3.10 on Win10.

import asyncio

async def func_2():
    await asyncio.sleep(2.0)
    return 42

async def func_1():
    my_task = asyncio.create_task(func_2())
    i = 0
    while not my_task.done():
        print(f"\rProgress: el{i}", end='')
        await asyncio.sleep(0.4)
        i += 1
    return my_task.result()

print('\nDone...', asyncio.run(func_1()))

Upvotes: 2

Related Questions