1. <small id='9pNmS'></small><noframes id='9pNmS'>

    2. <legend id='9pNmS'><style id='9pNmS'><dir id='9pNmS'><q id='9pNmS'></q></dir></style></legend>
        <bdo id='9pNmS'></bdo><ul id='9pNmS'></ul>
    3. <tfoot id='9pNmS'></tfoot>

      <i id='9pNmS'><tr id='9pNmS'><dt id='9pNmS'><q id='9pNmS'><span id='9pNmS'><b id='9pNmS'><form id='9pNmS'><ins id='9pNmS'></ins><ul id='9pNmS'></ul><sub id='9pNmS'></sub></form><legend id='9pNmS'></legend><bdo id='9pNmS'><pre id='9pNmS'><center id='9pNmS'></center></pre></bdo></b><th id='9pNmS'></th></span></q></dt></tr></i><div id='9pNmS'><tfoot id='9pNmS'></tfoot><dl id='9pNmS'><fieldset id='9pNmS'></fieldset></dl></div>

      在单独的线程中执行 run_coroutine_threadsafe

      时间:2023-10-11

          <i id='csQHf'><tr id='csQHf'><dt id='csQHf'><q id='csQHf'><span id='csQHf'><b id='csQHf'><form id='csQHf'><ins id='csQHf'></ins><ul id='csQHf'></ul><sub id='csQHf'></sub></form><legend id='csQHf'></legend><bdo id='csQHf'><pre id='csQHf'><center id='csQHf'></center></pre></bdo></b><th id='csQHf'></th></span></q></dt></tr></i><div id='csQHf'><tfoot id='csQHf'></tfoot><dl id='csQHf'><fieldset id='csQHf'></fieldset></dl></div>

          1. <tfoot id='csQHf'></tfoot>

            <small id='csQHf'></small><noframes id='csQHf'>

          2. <legend id='csQHf'><style id='csQHf'><dir id='csQHf'><q id='csQHf'></q></dir></style></legend>
                <tbody id='csQHf'></tbody>
                <bdo id='csQHf'></bdo><ul id='csQHf'></ul>
                本文介绍了在单独的线程中执行 run_coroutine_threadsafe的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                我有一个永远运行的脚本(它检查文件的变化).每当制作奇怪的文件时,我都需要发送 Discord 消息.

                I have a script that is constantly running forever (it checks changes in files). I need to send Discord messages whenever a weird file is made.

                • 问题是,事件监听函数(下面的def run(self):)来自一个子类,所以我不能把它改成async def run(self):.因此我不能使用 await channel.send()
                • 我对此的解决方案是使用 run_coroutine_threadsafe,如下所述:https://stackoverflow.com/一个/53726266/9283107.效果很好!但问题是,消息被放入队列中,并且在此脚本完成之前它们永远不会被发送(在我的情况下是:永远不会).我假设发送消息函数被放入该脚本所在的线程中,因此线程永远不会到达它们?
                • Problem is, the event watching function (def run(self): below) is from a subclass, so I can't change it to async def run(self):. Therefore I can't use await channel.send()
                • My solution to this was to use run_coroutine_threadsafe like explained here: https://stackoverflow.com/a/53726266/9283107. That works good! But the problem is, the messages get put into a queue and they never get sent until this script finishes (which in my case would be: never). I assume the send message functions get put into the thread that this script is on, therefore the thread never gets to them?

                也许我们可以将 run_coroutine_threadsafe 扔到一个单独的线程中或什么的?这是我能做的最小的例子,它仍然显示了我的子类问题.

                Maybe we can throw the run_coroutine_threadsafe into a separate thread or something? This is the most minimal example I can make that still shows my subclass problem.

                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')
                

                推荐答案

                首先,请注意,您不能从 async 调用阻塞代码,例如 time.sleep()定义.要启动一个阻塞函数并让它与 asyncio 通信,您可以从 on_ready 甚至从顶层生成一个后台线程,如下所示:

                First, note that you're not allowed to call blocking code such as time.sleep() from an async def. To start a blocking function and have it communicate with asyncio, you can spawn a background thread from on_ready or even from top-level, like this:

                # checker_function is the function that blocks and that
                # will invoke Example.run() in a loop.
                threading.Thread(
                    target=checker_function,
                    args=(asyncio.get_event_loop(), channel)
                ).start()
                

                您的主线程将运行 asyncio 事件循环,而您的后台线程将检查文件,使用 asyncio.run_coroutine_threadsafe() 与 asyncio 和 discord 进行通信.

                Your main thread will run the asyncio event loop and your background thread will check the files, using asyncio.run_coroutine_threadsafe() to communicate with asyncio and discord.

                正如您链接到的答案下的评论中指出的那样,asyncio.run_coroutine_threadsafe 假定您有多个线程正在运行(因此是线程安全的"),其中一个运行事件循环.在您实现之前,任何使用 asyncio.run_coroutine_threadsafe 的尝试都会失败.

                As pointed out in a comment under the answer you linked to, asyncio.run_coroutine_threadsafe assumes that you have multiple threads running (hence "thread-safe"), one of which runs the event loop. Until you implement that, any attempt to use asyncio.run_coroutine_threadsafe will fail.

                这篇关于在单独的线程中执行 run_coroutine_threadsafe的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                    <tfoot id='vuUpK'></tfoot>

                    <small id='vuUpK'></small><noframes id='vuUpK'>

                        <tbody id='vuUpK'></tbody>

                      <i id='vuUpK'><tr id='vuUpK'><dt id='vuUpK'><q id='vuUpK'><span id='vuUpK'><b id='vuUpK'><form id='vuUpK'><ins id='vuUpK'></ins><ul id='vuUpK'></ul><sub id='vuUpK'></sub></form><legend id='vuUpK'></legend><bdo id='vuUpK'><pre id='vuUpK'><center id='vuUpK'></center></pre></bdo></b><th id='vuUpK'></th></span></q></dt></tr></i><div id='vuUpK'><tfoot id='vuUpK'></tfoot><dl id='vuUpK'><fieldset id='vuUpK'></fieldset></dl></div>
                      • <bdo id='vuUpK'></bdo><ul id='vuUpK'></ul>
                        <legend id='vuUpK'><style id='vuUpK'><dir id='vuUpK'><q id='vuUpK'></q></dir></style></legend>