英文:
How do i set a runmode for a slash command in discord.net?
问题
官方discord.net API仅显示这个文本命令,但我对SlashCommandExecuter阻塞网关任务有问题。我使用以下代码初始化命令:
public async Task Client_Ready()
{
var client = _Provider.GetRequiredService<DiscordSocketClient>();
var ExampleCommand = new SlashCommandBuilder()
.WithName("examplecommand")
.WithDescription("This is a long running command");
try
{
await client.CreateGlobalApplicationCommandAsync(ExampleCommand.Build());
}
catch (HttpException exception)
{
var json = JsonConvert.SerializeObject(exception.Errors, Formatting.Indented);
Console.WriteLine(json);
}
}
并在主Async中处理它们,使用交互SlashCommandExecuted和一个单独的任务以command.Data.Name开关。
我在SlashCommandBuilder和RespondAsync中搜索了这个参数。我知道我可以在CommandService配置中设置runmode,但我不需要所有命令都是异步runmode。有没有办法绕过这个?AI也经常没有给出有效的答案,通常写一些混乱的代码或者展示它与ModuleBase的使用。我找到了一个可能的选项,但也不起作用:
private async Task SlashCommandHandler(SocketSlashCommand command)
{
await Task.Run(async () =>
{
// 执行一些长时间运行的任务
await Task.Delay(5000);
// 响应命令
await command.RespondAsync("命令已完成。");
});
}
英文:
The official discord.net API shows this only for a text-based commands but i have a problem with the SlashCommandExecuter blocking the gateway task. I initialize commands using this code:
public async Task Client_Ready()
{
var client = _Provider.GetRequiredService<DiscordSocketClient>();
var ExampleCommand = new SlashCommandBuilder()
.WithName("examplecommand")
.WithDescription("This is a long running command");
try
{
await client.CreateGlobalApplicationCommandAsync(ExampleCommand.Build());
}
catch (HttpException exception)
{
var json = JsonConvert.SerializeObject(exception.Errors, Formatting.Indented);
Console.WriteLine(json);
}
}
And handle them using interaction SlashCommandExecuted in the Main Async and a separate task with command.Data.Name switch.
I searched for this parameter in the SlashCommandBuilder and also in RespondAsync. I know that i can set runmode in the CommandService config but i do not need async runmode in all of my commands. Is there any way around it? AI also doesn't give any valid answer often writing some spagetti code or showing the use of it with the ModuleBase. I found one possible option but it doesn't work either:
private async Task SlashCommandHandler(SocketSlashCommand command)
{
await Task.Run(async () =>
{
// Do some long-running task
await Task.Delay(5000);
// Respond to the command
await command.RespondAsync("Command completed.");
});
}
答案1
得分: 0
如果你不想让异步代码阻塞主线程,你应该fire and forget它。所以不要等待你的任务:
_ = Task.Run(async () =>
{
// 执行一些长时间运行的任务
await Task.Delay(5000);
// 响应命令
await command.RespondAsync("命令完成。");
});
尽管如此,我建议你看一下交互框架。 这与TextCommands的类似。你可以像这样使用一个属性:
[SlashCommand("test", "一个示例描述", runMode: RunMode.Async)]
public async Task TestCommand(string test)
{
// 做一些事情。
}
英文:
If you don't want your async code to block the Main Thread you should fire and forget it. So don't await your Task:
_ = Task.Run(async () =>
{
// Do some long-running task
await Task.Delay(5000);
// Respond to the command
await command.RespondAsync("Command completed.");
});
Nevertheless, I would recommend that you take a look at the Interaction Framework.
This is very similar to the one for the TextCommands. There you can just use an Attribute like this:
[SlashCommand("test", "A sample description", runMode: RunMode.Async)]
public async Task TestCommand(string test)
{
// do smth.
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论