同时执行一个异步函数
execute an async function concurrently
我正在尝试为 discord 机器人发出命令,使机器人执行可能很长的操作。所以我想在每个关键步骤之前发送消息通知用户。
但是,由于网络限制,发送消息可能需要一些时间,因此会进一步降低程序速度。
工作代码
当我调用 return 没有值的函数时,它可以按以下方式正常工作:
import discord
import requests
import asyncio
with requests.Session() as session:
await asyncio.gather(
ctx.send("Connecting to the server"),
init_session(session)
)
字典类型错误
但是,问题是后来,我使用了一个 return 字典的函数 :
result = await asyncio.gather(
ctx.send("Connecting to the server"),
get_dict(session)
)
然后,它给了我以下错误:asyncio gather TypeError: unhashable type: 'dict'
线程运行时出错
我也尝试在另一个线程中执行 send
函数:
t = threading.Thread(target=asyncio.run, args=[ctx.send("Getting result")])
t.start()
但是我又遇到了另一个错误:RuntimeError: Task <Task pending name='Task-20' coro=<Messageable.send() running at [my discord library directory]> cb=[_run_until_complete_cb() at [my asyncio directory]\base_events.py:184]> got Future <Future pending> attached to a different loop
所以,如果有人知道更好的方法,我将非常感激。
当您使用异步函数时,只允许某些 return 类型。这些类型需要是“可散列的”。无法直接编辑可哈希项(如列表或字典),而是存储的数据是常量(如元组或整数)(see this answer)。
因此,针对您的错误的一种解决方案是为 get_dict-function 使用另一种数据类型(我想在这种情况下您也应该重命名该函数)。
如果您不想更改太多并且在创建后从不更改您的词典的任何内容,请考虑在 return 之前将其转换为 hashable version。
字典不是 asyncio.gather
的有效参数,因为它需要一个等待对象列表。
如果你想保持 get_dict
函数的当前定义,你必须将它包装到一个可等待的对象中,即使用 loop.run_in_executor
:
loop = asyncio.get_running_loop()
result = await asyncio.gather(
ctx.send("Connecting to the server"),
loop.run_in_executor(None, get_dict, session)
)
我正在尝试为 discord 机器人发出命令,使机器人执行可能很长的操作。所以我想在每个关键步骤之前发送消息通知用户。
但是,由于网络限制,发送消息可能需要一些时间,因此会进一步降低程序速度。
工作代码
当我调用 return 没有值的函数时,它可以按以下方式正常工作:
import discord
import requests
import asyncio
with requests.Session() as session:
await asyncio.gather(
ctx.send("Connecting to the server"),
init_session(session)
)
字典类型错误
但是,问题是后来,我使用了一个 return 字典的函数 :
result = await asyncio.gather(
ctx.send("Connecting to the server"),
get_dict(session)
)
然后,它给了我以下错误:asyncio gather TypeError: unhashable type: 'dict'
线程运行时出错
我也尝试在另一个线程中执行 send
函数:
t = threading.Thread(target=asyncio.run, args=[ctx.send("Getting result")])
t.start()
但是我又遇到了另一个错误:RuntimeError: Task <Task pending name='Task-20' coro=<Messageable.send() running at [my discord library directory]> cb=[_run_until_complete_cb() at [my asyncio directory]\base_events.py:184]> got Future <Future pending> attached to a different loop
所以,如果有人知道更好的方法,我将非常感激。
当您使用异步函数时,只允许某些 return 类型。这些类型需要是“可散列的”。无法直接编辑可哈希项(如列表或字典),而是存储的数据是常量(如元组或整数)(see this answer)。
因此,针对您的错误的一种解决方案是为 get_dict-function 使用另一种数据类型(我想在这种情况下您也应该重命名该函数)。
如果您不想更改太多并且在创建后从不更改您的词典的任何内容,请考虑在 return 之前将其转换为 hashable version。
字典不是 asyncio.gather
的有效参数,因为它需要一个等待对象列表。
如果你想保持 get_dict
函数的当前定义,你必须将它包装到一个可等待的对象中,即使用 loop.run_in_executor
:
loop = asyncio.get_running_loop()
result = await asyncio.gather(
ctx.send("Connecting to the server"),
loop.run_in_executor(None, get_dict, session)
)