0

I am trying to use asyncio together with threading for a Discord Bot. I've found this script which I changed to my needs:

import time
import threading as th
import asyncio
import discord

class discordvars(object):
    client=discord.Client()
    TOKEN=('---')
    running_discordthread=False

    discordloop = asyncio.get_event_loop()
    discordloop.create_task(client.start(TOKEN))
    discordthread=th.Thread(target=discordloop.run_forever)

def start():
    if discordvars.running_discordthread==False:
        discordvars.discordthread.start()
        print("Discord-Client started...")
        discordvars.running_discordthread=True
    else:
        print("Discord-CLient allready running...")
    time.sleep(2)
    
def stop():
    if discordvars.running_discordthread==True:
        discordvars.discordloop.call_soon_threadsafe(discordvars.discordloop.stop())
        print("Requestet Discord-Client stop!")
        discordvars.discordthread.join()
        print(discordvars.discordthread.isAlive())
        time.sleep(1)
        print("Discord-Client stopped...")
        discordvars.running_discordthread=False
    else:
        print("Discord-Client not running...")
    time.sleep(2)


@discordvars.client.event
async def on_message(message):
    if message.content.startswith('!test'):
        embed = discord.Embed(title="test", color=0x0071ce, description="test")
        await message.channel.send(embed=embed)

Starting the Script with the start() function works great. Also stopping with the stop() function works somehow. If I call the stop() function it prints: "False" so I am thinking that the thread was stopped. But if I then call the start() function I will get an error:

RuntimeError: threads can only be started once

This script is part of a big project so I am calling the functions from another script. But I think that shouldn't be the problem.

What is the problem? Thanks in advance.

1 Answer 1

0

You cannot re-start the existing thread, but you can start a new thread that runs the event loop. You can achieve that by moving the assignment to discordthread to the start function.

And your call to call_soon_threadsafe is wrong. You need to pass discordloop.stop to it, without parentheses. That refers to the actual function without calling it right away, and allows the loop thread to call it, which was intended:

discordloop.call_soon_threadsafe(discordloop.stop)

Finally, your init function is missing a global declaration for the variables you assign that are intended as globals.

Sign up to request clarification or add additional context in comments.

8 Comments

I think my Question wasn't formulated well. Sorry. So I edited my Question and now it should be a little bit clearer. I tried putting discord thread inside of start/stop but I am still getting the error.
@Paul Sorry, but now it's even less clear than before. You are accessing attributes of init which the script you've shown never sets. Also you mention what you tried, but you didn't show that code - how can we tell what's wrong? You need to show the exact script you are running, just removing the discord event handling for brevity.
I am really sorry. My native language isn't English. I tried my best to explain it well. The code wich is postet above is the exact code I am running.
@Paul It cannot be exact code because there is no top-level code that will start asyncio or discord or just invoke discordfunction() and others. Also, the syntax is incorrect due to inconsistent indentation, Python would never accept it. If you want help, please post your actual code and take care to copy it correctly.
It seems like the last time I edited the code it somehow didn't change. So now it's the 100% exact code I am using. I only removed the Token. I can't post my main script here because it's way too long but the only thing what I am doing in the main script is importing the start() and stop() functions and then executing them.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.