我有一个永远运行的脚本(它检查文件中的更改)。每当制作一个奇怪的文件时,我需要发送不和谐的消息
def run(self):
)来自子类,所以我不能将其更改为async def run(self):
。因此,我不能使用await channel.send()
run_coroutine_threadsafe
,就像这里解释的:https://stackoverflow.com/a/53726266/9283107。那很好!但问题是,消息被放入一个队列中,在这个脚本完成之前它们永远不会被发送(在我的例子中是:从不)。我假设发送消息函数被放入这个脚本所在的线程中,因此线程永远无法访问它们李>也许我们可以把run_coroutine_threadsafe
放进一个单独的线程或者别的什么?这是我能做的最简单的例子,它仍然显示了我的子类问题
import discord
import os
import asyncio
import time
# CHANNEL_ID = 7659170174????????
client = discord.Client()
channel = None
class Example():
# Imagine this run comes from a subclass, so you can't add sync to it!
def run(self):
# await channel.send('Test') # We can't do this because of the above comment
asyncio.run_coroutine_threadsafe(channel.send('Test'), _loop)
print('Message sent')
@client.event
async def on_ready():
print('Discord ready')
global channel
channel = client.get_channel(CHANNEL_ID)
for i in range(2):
Example().run()
time.sleep(3)
print('Discord messages should appear by now. Sleeping for 20s to give it time (technically this would be infinite)')
time.sleep(20)
print('Script done. Now they only get sent for some reason')
_loop = asyncio.get_event_loop()
client.run('Your secret token')
在对这个问题发表了
user4815162342
评论之后,我想到了这个,它非常有效首先,请注意,不允许从
async def
调用诸如time.sleep()
之类的阻塞代码。要启动阻塞函数并使其与asyncio通信,可以从on_ready
甚至从顶层生成一个后台线程,如下所示:主线程将运行asyncio事件循环,后台线程将检查文件,使用
asyncio.run_coroutine_threadsafe()
与asyncio和discord通信正如您链接到的答案下面的注释所指出的,
asyncio.run_coroutine_threadsafe
假设您有多个线程正在运行(因此是“线程安全的”),其中一个线程运行事件循环。在实现该功能之前,任何使用asyncio.run_coroutine_threadsafe
的尝试都将失败相关问题 更多 >
编程相关推荐