import asyncio
from threading import Thread, Event
class wk:
def __init__(self):
self.th: Thread
self.loop = asyncio.new_event_loop()
def _cancel_all(self):
if tks := asyncio.all_tasks(self.loop):
for task in tks:
task.cancel()
self.loop.run_until_complete(asyncio.gather(*tks, return_exceptions=True))
def _doing(self):
asyncio.set_event_loop(self.loop)
try:
self.loop.run_forever()
finally:
self._cancel_all()
self.loop.run_until_complete(self.loop.shutdown_asyncgens())
self.loop.close()
def __enter__(self):
(th := Thread(target=self._doing, daemon=True)).start()
self.th = th
return self
def __exit__(self, a, b, c):
self.loop.call_soon_threadsafe(self.loop.stop)
self.th.join()
del self.th
def arun(self, coro):
ev = Event()
async def wrapper():
await coro
ev.set()
self.loop.call_soon_threadsafe(self.loop.create_task, wrapper())
return ev
if __name__ == "__main__":
async def demo_task(i):
print(f"Task {i} enter")
await asyncio.sleep(0.1 * i)
print(f"Task {i} done ")
with wk() as w:
for i in range(15):
w.arun(demo_task(i))
ev = w.arun(demo_task(15))
ev.wait()