所以我有一个基本的discord bot接受输入
import discord
import asyncio
import threading
loop = asyncio.new_event_loop()
bot = discord.Client()
def run_asyncio_loop(loop):
asyncio.set_event_loop(loop)
loop.run_forever()
Hangman.set_bot(bot)
@bot.event
async def on_message(message):
bot.loop.create_task(Hangman.main(message))
asyncioLoop = threading.Thread(target = run_asyncio_loop, args = (loop,))
asyncioLoop.start()
bot.run(BotConstants.TOKEN)
在这个例子中,它调用了hangman游戏,它不会阻止任何东西,因为我使用asyncio.sleep(n)
测试了这个但是当我在hangman中做某事时会阻止它。
class Hangman():
async def main(message):
await Hangman.make_guess(message)
async def update_score(message):
sheetLoaded = Spreadsheet.load_ws(...)
userExists = Spreadsheet.user_exists(...)
if (not userExists):
Spreadsheet.add_user(...)
Spreadsheet.add_score(...)
await Hangman.bot.send_message(message.channel, msg)
elif (not sheetLoaded):
await Hangman.bot.send_message(message.channel, msg)
async def make_guess(message):
# perform guess
if (matched):
await Hangman.bot.send_message(message.channel, msg)
Hangman.GAMES.pop(message.server.id)
await Hangman.update_score(message)
调用Hangman.update_score()
时会阻止它。所以它不会处理任何命令,直到分数更新,这意味着大约5秒左右(不长但很多用户发送垃圾邮件是一个问题)机器人不接受任何其他消息
我还缺少什么能让这个过程在后台运行同时仍接受新的输入?
答案 0 :(得分:1)
Asyncio仍然是单线程的。事件循环运行的唯一方法是没有其他协同程序正在执行。使用from / await中的yield会暂时挂起协同程序,从而为事件循环提供工作机会。因此,除非您使用yield (from)
或await
或return
调用其他协程,否则会阻止该进程。您可以在await asyncio.sleep(0)
的步骤之间添加Hangman.update_score
,以便在多个部分中划分流程阻止,但这只能确保减少“挂起”时间,而不会实际加快您的线程。
要使该过程实际在后台运行,您可以尝试以下方式:
from concurrent.futures import ProcessPoolExecutor
executor = ProcessPoolExecutor(2)
asyncio.ensure_future(loop.run_in_executor(executor, Hangman.update_score(message)))