【问题标题】:Cannot close a running event loop无法关闭正在运行的事件循环
【发布时间】:2021-06-12 20:13:28
【问题描述】:

任务完成后关闭 discord.py bot 循环的方法是什么?

添加:

nest_asyncio.apply()

试过了:

bot.logout(), bot.close(), bot.cancel()

代码:

async def helper(bot, discord_user_feed):
    nest_asyncio.apply()
    await bot.wait_until_ready()
    # await asyncio.sleep(10)
    for each_id, events_list in discord_user_feed.items():
        discord_user = await bot.fetch_user(int(each_id))
        for each_one in events_list:
            msg_sent = True
            while msg_sent:
                await discord_user.send(each_one)
                msg_sent = False
    await bot.close()
    return 'discord messages sent'


async def discord_headlines(request):
    nest_asyncio.apply()
    discord_user_feed =  await get_details()
    bot = commands.Bot(command_prefix='!')
    bot.loop.create_task(helper(bot, discord_user_feed))
    message = bot.run('my_token')
    return HttpResponse(message)

我可以使用 id 和 discord bot 向 discord 用户发送消息。但是,即使在此之后,django view api 仍在继续运行并出现错误。它需要返回响应消息 - 发送不和谐消息。

错误:

Exception in callback <TaskWakeupMethWrapper object at 0x000001C852D2DA38>(<Future finis...SWdZVtXT7E']}>)
handle: <Handle <TaskWakeupMethWrapper object at 0x000001C852D2DA38>(<Future finis...SWdZVtXT7E']}>)>
Traceback (most recent call last):
  File "E:\sd\envs\port\lib\asyncio\events.py", line 145, in _run
    self._callback(*self._args)
KeyError: <_WindowsSelectorEventLoop running=True closed=False debug=False>
Internal Server Error: /api/v0/discord_headlines/
Traceback (most recent call last):
  File "E:\sd\envs\port\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "E:\sd\envs\port\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\sd\envs\port\lib\site-packages\asgiref\sync.py", line 139, in __call__
    return call_result.result()
  File "E:\sd\envs\port\lib\concurrent\futures\_base.py", line 425, in result
    return self.__get_result()
  File "E:\sd\envs\port\lib\concurrent\futures\_base.py", line 384, in __get_result
    raise self._exception
  File "E:\sd\envs\port\lib\site-packages\asgiref\sync.py", line 204, in main_wrap
    result = await self.awaitable(*args, **kwargs)
  File "E:\back-end\port_api\views\discord_integration.py", line 110, in discord_headlines
    message = bot.run('my_token')
  File "E:\sd\envs\port\lib\site-packages\discord\client.py", line 719, in run
    _cleanup_loop(loop)
  File "E:\sd\envs\port\lib\site-packages\discord\client.py", line 95, in _cleanup_loop
    loop.close()
  File "E:\sd\envs\port\lib\asyncio\selector_events.py", line 107, in close
    raise RuntimeError("Cannot close a running event loop")
RuntimeError: Cannot close a running event loop
[13/Jun/2021 01:07:34] "GET /api/v0/discord_headlines/ HTTP/1.1" 500 109010

这些是版本:

Python 3.6.4, Django 3.1, discord.py 1.7.3, Asyncio, Anaconda-4.9.2, Windows-10

【问题讨论】:

    标签: python python-3.x django discord.py python-asyncio


    【解决方案1】:

    我没有使用旧版本,因此我无法证明此答案对于 2021 年前版本 (v1.6.0+) Discord.py 的准确性。

    当通过run(*args, **kwargs) 启动不和谐客户端或机器人时,实际上没有类方法可以阻止它。

    根据 Discord.py 文档Discord.py discord.Client.run

    一个阻塞调用,将事件循环初始化从 你。

    如果你想更多地控制事件循环,那么这个函数应该 不被使用。使用 start() 协程或 connect() + login()

    它实际上等于:

    # run(*args, **kwargs) is basically
    try:
        # Start the bot on asyncio event loop with using .start() coroutine
        loop.run_until_complete(start(*args, **kwargs))
    except KeyboardInterrupt:
        # Invoke close() coroutine on the same loop if interrupt
        loop.run_until_complete(close())
        # Cancel any other lingering tasks and such
    finally:
        loop.close()
    

    因此,您当前尝试实施的无回报但准确的答案很简单......您不能。

    如果您想在您使用的网络服务器库上提供更多信息作为响应或通过消息,我可以帮助您制作一些实用的东西。

    如果您的网络服务器完全集成了 asyncio,那么最好的办法是查看库是否有办法将任务添加到其现有的事件循环中,或者您是否将任务传递给它。 Sanic 在其装饰器启动/关闭方法(例如 after_server_start 等)中允许这样做。将机器人实例的引用存储在某处并根据需要传递它。

    我会尝试关注这里的回复或 DM,并尝试帮助您发挥作用,我们可以在此处发布更新的代码答案,在更复杂的情况下使用 discord.py 非常缺乏可靠的答案在其他应用程序/网络服务中,我在编写一个 discord.py 机器人时遇到了类似的问题,该机器人接受 webhook 数据并根据某些过滤器将嵌入发布到适当的频道。

    【讨论】:

    • 这个我已经试过了,但是没用。谢谢。
    猜你喜欢
    • 2020-06-23
    • 1970-01-01
    • 1970-01-01
    • 2022-10-30
    • 2021-11-17
    • 2020-08-02
    • 1970-01-01
    • 2019-12-29
    • 2021-01-25
    相关资源
    最近更新 更多