web-dev-qa-db-ja.com

ランタイムエラー:イベントループが実行されています

関数send_messageを呼び出すと、次のエラーが発生します。

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.4/threading.py", line 868, in run
    self._target(*self._args, **self._kwargs)
  File "/home/joffe/Documents/discord/irc/ircbot.py", line 44, in get_message
    mydiscord.send_message(line[1])
  File "/home/joffe/Documents/discord/irc/mydiscord.py", line 37, in send_message
    client.loop.run_until_complete(client.send_message(SERVER,message))
  File "/usr/lib/python3.4/asyncio/base_events.py", line 331, in run_until_complete
    self.run_forever()
  File "/usr/lib/python3.4/asyncio/base_events.py", line 296, in run_forever
    raise RuntimeError('Event loop is running.')
RuntimeError: Event loop is running.

私の関数send_messageはメッセージを受け取り、それをディスコードチャネルに送信します。関数は、スレッドで実行されている関数から呼び出されます。クライアントオブジェクトはメインスレッドで作成されます。

def send_message(message):
    print(str.encode("Message to discord: " + message))

    client.loop.run_until_complete(client.send_message(SERVER,message))
13
Olof

(おそらく別のスレッドで)既に実行されているループでloop.run_until_completeを呼び出すと、「イベントループが実行されています」という例外しか表示されません。

ループがすでに別のスレッドで実行されていて、実行するコルーチンを送信する場合は、次のコマンドを使用します。

asyncio.run_coroutine_threadsafe(client.send_message(SERVER, message), client.loop)

ループにコルーチンを追加しようとしていて、そのループが現在のスレッドで実行されている場合、最善の方法はおそらくawait/yield fromだけですが、それをスケジュールしている場合同期関数から、あなたはおそらく以下を望みます:

asyncio.ensure_future(
    client.send_message(SERVER, message),
    loop=client.loop
).add_done_callback(fn)

ここで、fnは、ensure_futureによって作成されたフューチャーのみがパラメーターであり、フューチャーが完了した後に呼び出される関数です。

15
Sean