Reputation: 31
There is no problem using asyncio as follows.
import asyncio
async def main():
await asyncio.sleep(1)
aaa = 1
print (aaa)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
However, I have to use asyncio within Thread as shown in the simple code below, which results in an error as follows
import asyncio
import threading
async def main():
await asyncio.sleep(1)
aaa = 1
print (aaa)
def test():
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
t=threading.Thread(target=test)
t.start()
Error Message (RuntimeError: There is no current event loop in thread 'Thread-1'.)
Exception in thread Thread-1:
Traceback (most recent call last):
File "D:\Anaconda3\Lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "D:\Anaconda3\Lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "D:/Test/Test4/main.py", line 57, in test
loop = asyncio.get_event_loop()
File "D:\Anaconda3\Lib\asyncio\events.py", line 639, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.
How can I use asyncio in Thread?
This is very important to me. I've been struggling with this problem for two days.
I would appreciate your help.
Upvotes: 3
Views: 3870
Reputation: 52099
Unless you need to work with a pre-existing event loop (not the case here) or support Python 3.6, use asyncio.run
instead of manually handling the loop:
def test():
asyncio.run(main())
This always ensures that there is a valid event loop, and also handles proper cleanup.
This function always creates a new event loop and closes it at the end. It should be used as a main entry point for asyncio programs, and should ideally only be called once.
Note that when combining asyncio
with threads, the event loop should generally be run in the main loop (see e.g. bpo#34697). Instead of spawning a thread for asyncio
, prefer to spawn one for the synchronous parts of your program.
# launch synchronous work in child threads
t=threading.Thread(target=my_sync_tasks)
t.start()
# launch asynchronous work in main thread
asyncio.run(main())
t.join()
Upvotes: 3
Reputation: 50949
When using a thread other than the main thread you need to set the event loop
def test():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())
loop.close()
Upvotes: 1