Reputation: 25
I'm programming Discord bot and I went into a big problem. I am programming RPG bot so I need to write player's HP and enemy's hp really often so I've made a function.
private void showHP(CommandEventArgs e)
{
client.ExecuteAndWait(async() =>
{
await e.Channel.SendMessage(userInside + " - " + player.HP);
});
}
That CommandEventArgs e comes from Command function since I need to access the channel where that command has been executed.
commands.CreateCommand("attack").Do(async (e) =>
{
await e.Channel.SendMessage("You have attacked");
showHP(e);
}
Everything seems to work pretty well... Until it is executed. The whole bot stucks and it is endlessly waiting, so I think I've used async and wait commands wrongly. If I don't use them at all the message is falling into timeout.
Upvotes: 1
Views: 2857
Reputation: 15151
If you want to follow the right pattern for async then modify your code as follow:
private Task showHP(CommandEventArgs e)
{
return e.Channel.SendMessage($"{userInside} - {player.HP}");
}
And do the call as follow:
commands.CreateCommand("attack")
.Do(async (e) =>
{
await e.Channel.SendMessage("You have attacked");
await showHP(e);
}
Creating a task to run a function as async and don't await that task is just useless, just call the async function without await and return the task, it will prevent the task planner to split the code on different context switches.
Upvotes: 1
Reputation: 331
client.ExecuteAndWait()
blocks the calling context until the parent DiscordClient
, (in your case, client
) disconnects.
This is not the proper way to create an asynchronous context - the easiest way of doing so would be to wrap your code in a Task.Run
, like so:
private void showHP(CommandEventArgs e)
{
Task.Run(async () => {
await e.Channel.SendMessage($"{userInside} - {player.HP}");
});
}
Upvotes: 4