1

I am working on a ayncio module and having issues in terminating program. I am running my program in terminal and Ctrl + C is not working to stop the running program.However, if I close the terminal and try to run program again, I get this issue :

INFO:root:In main
ERROR:root:This event loop is already running

Below is my sample code for understanding.

# all_tasks.py

import asyncio
import logging
# module imports
import settings

#configure logging into a file
logging.basicConfig(filename=settings.LOG_FILENAME,level=logging.DEBUG)


class AsyncTest(object):

    async def taskOne(self):
        while True:
            print("Task One") # Print is just an example, I am doing lot of stuff inside.
            await asyncio.sleep(60)

    async def taskTwo(self):
        while True:
            print("Task Two") # Print is just an example, I am doing lot of stuff inside.
            await asyncio.sleep(60) 

    async def main(self):
        try:
            loop = asyncio.get_event_loop()
                tasks = [
                        asyncio.ensure_future(self.taskOne()),
                        asyncio.ensure_future(self.taskTwo()),
                        ]
            loop.run_until_complete(asyncio.wait(tasks))
        except RuntimeError as error:
            logging.info("In main")
            logging.error(error)

if __name__ == '__main__':
    asynctest = AsyncTest()
    asyncio.run(asynctest.main())

Config: Windows 10, python 3.7.0

File Name: all_tasks.py

Command: python all_tasks.py

Any help is much appreciated. Thanks

1 Answer 1

2

asyncio.run creates and runs event loop. You shouldn't create and run one, especially inside a coroutine (function defined with async def). In a coroutine you should only await for something.

Modify the code accordingly:

# ...

    async def main(self):
        tasks = [
            asyncio.ensure_future(self.taskOne()),
            asyncio.ensure_future(self.taskTwo()),
        ]
        await asyncio.wait(tasks)

if __name__ == '__main__':
    asynctest = AsyncTest()
    asyncio.run(asynctest.main())

It'll work.

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

6 Comments

Thanks @mikhail, it worked. Also, Is there any good article on understanding asyncio in python. I found few online, but they are mainly on abstract level.
@Sam you're welcome. Take a look at the post here, it tries to give overall overview. Feel free to ask if you're interested in something particular.
what if taskOne() has to use loop. run_until_complete() to make it a sync function, while main() has to be an async function? How can I avoid the error then?
@EmersonXu you shouldn't use run_until_complete() inside async functions. Please read this answer for more details.
@EmersonXu most high-level legacy functions that should be sync can be run asynchronously in thread using run_in_executor. It is a common way to cast some sync function you can't rewrite to async coroutine. But after all this, in the end, on very top of the final program should be single event loop that runs some top-level coroutine.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.