2

Could anyone give me a tip on how to run asyncio script to stop when complete? I know its something to do with how I am setting the main loop to run... in this portion of the complete code but what ever I try from what I can find online it doesnt work.

loop = asyncio.get_event_loop()

try:
    asyncio.ensure_future(firstWorker())
    asyncio.ensure_future(secondWorker())
    loop.run_forever()

The script below is just something made up attempting to compile randon data into a pandas dataframe when the script completes but I cant get it to complete! Any tips greatly appreciated...

complete code:

import asyncio
import pandas as pd
from datetime import datetime
import random


data = []

async def firstWorker():
    for _ in range(5):
        await asyncio.sleep(1)

        things = {}

        stamp = datetime.now()

        temperature1 = (random.random() * 20) - 5
        print(temperature1)

        things['Date'] = stamp
        things['temperature1'] = temperature1

        data.append(things)



async def secondWorker():
    for _ in range(5):
        await asyncio.sleep(1)

        stuff = {}

        stamp = datetime.now()

        temperature2 = (random.random() * 40) - 15
        print(temperature2)

        stuff['Date'] = stamp
        stuff['temperature2'] = temperature2


        data.append(stuff)



loop = asyncio.get_event_loop()

try:
    asyncio.ensure_future(firstWorker())
    asyncio.ensure_future(secondWorker())
    loop.run_forever()

except KeyboardInterrupt:
    pass

finally:
    print("Closing Loop")
    loop.close()


    master_data = pd.DataFrame(data)
    master_data.columns = ['Date','temperature1','temperature2']

    master_data.to_csv('master_data.csv')
bbartling
  • 3,288
  • 9
  • 43
  • 88

1 Answers1

1

You probably want asyncio.gather and run_until_complete

async def main():
    await asyncio.gather(firstWorker(), secondWorker())

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
ConorSheehan1
  • 1,640
  • 1
  • 18
  • 30
  • If you care about the order of results you may want to use `asyncio.gather` instead of `asyncio.wait`. See https://stackoverflow.com/questions/34377319/combine-awaitables-like-promise-all – ConorSheehan1 Jun 10 '20 at 21:05
  • If you are using python >= 3.7 you can simplify the last 3 lines to `asyncio.run(main())`. See https://stackoverflow.com/questions/52796630/python3-6-attributeerror-module-asyncio-has-no-attribute-run – ConorSheehan1 Jun 10 '20 at 21:16
  • Using asyncio.wait like this makes exceptions pass silently. Use asyncio.gather instead. – user4815162342 Jun 11 '20 at 11:44
  • In the main loop, `async def main(): await asyncio.gather([firstWorker(), secondWorker()])` If I use `asyncio.gather` instead of `asyncio.wait` this will throw an exception.. – bbartling Jun 11 '20 at 13:28
  • `Traceback (most recent call last): File "asyncioRand.py", line 51, in loop.run_until_complete(main()) File "C:\Users\benb\AppData\Local\Continuum\anaconda3\lib\asyncio\base_events.py", line 584, in run_until_complete return future.result() File "asyncioRand.py", line 48, in main await asyncio.gather([firstWorker(), secondWorker()]) File "C:\Users\benb\AppData\Local\Continuum\anaconda3\lib\asyncio\tasks.py", line 718, in gather if arg not in arg_to_fut: TypeError: unhashable type: 'list' – bbartling Jun 11 '20 at 13:29
  • `gather` takes multiple arguments, `wait` takes a list. If you want to use `gather`, you need `asyncio.gather(firstWorker(), secondWorker())` – ConorSheehan1 Jun 11 '20 at 13:57