Проблема проста, в каждом потоке есть один цикл по умолчанию.Который установлен asyncio.set_event_loop(loop)
.Затем вы можете получить этот цикл с помощью loop = asyncio.get_event_loop()
.
Так что проблема, в основном, в том, что некоторые пакеты по умолчанию используют asyncio.get_event_loop()
для получения текущего запущенного цикла.Возьмем aiohttp
в качестве примера:
class aiohttp.ClientSession(*, connector=None, loop=None, cookies=None, headers=None, skip_auto_headers=None, auth=None, json_serialize=json.dumps, version=aiohttp.HttpVersion11, cookie_jar=None, read_timeout=None, conn_timeout=None, timeout=sentinel, raise_for_status=False, connector_owner=True, auto_decompress=True, requote_redirect_url=False, trust_env=False, trace_configs=None)
Как вы можете видеть, он принимает параметр loop
для указания работающего цикла.Но вы также можете просто оставить его пустым, чтобы использовать asyncio.get_event_loop()
по умолчанию.
Ваша проблема в том, что вы запускаете сопрограммы в новом созданном цикле.Но вы не можете подтвердить, что все ваши внутренние операции также используют эту новую созданную.Поскольку они могут использовать asyncio.get_event_loop()
, они будут присоединены к другому циклу, который является циклом по умолчанию в текущем потоке.
Насколько я думаю, вам не нужно создавать новый, но пусть это делают пользователи.Как и в примере выше, вы принимаете аргумент loop
, а если он равен None
, используйте аргумент по умолчанию.
Или вам нужно тщательно проверить свой код, чтобы убедиться, что все возможные сопрограммыиспользует созданный вами цикл.