RuntimeError: This event loop is already running in python

前端 未结 5 1189
攒了一身酷
攒了一身酷 2020-12-04 18:59

I think I\'m getting this error because my code calls asyncio.get_event_loop().run_until_complete(foo()) twice. Once from foo() and second time fr

5条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-04 19:28

    Using nest_asyncio didn't work for me, because then aiohttp started complaining with

    • RuntimeError: Timeout context manager should be used inside a task

    Instead I decided to replace all calls to asyncio.run with calls to this asyncio_run:

    def asyncio_run(future, as_task=True):
        """
        A better implementation of `asyncio.run`.
    
        :param future: A future or task or call of an async method.
        :param as_task: Forces the future to be scheduled as task (needed for e.g. aiohttp).
        """
    
        try:
            loop = asyncio.get_running_loop()
        except RuntimeError:  # no event loop running:
            loop = asyncio.new_event_loop()
            return loop.run_until_complete(_to_task(future, as_task, loop))
        else:
            nest_asyncio.apply(loop)
            return asyncio.run(_to_task(future, as_task, loop))
    
    
    def _to_task(future, as_task, loop):
        if not as_task or isinstance(future, Task):
            return future
        return loop.create_task(future)
    

    A secondary goal was to be able to think of asyncio.run as promise.resolve from the JS world, or Task.Wait from the .NET world.

提交回复
热议问题