所以,我正在制作一个能够在一定时间后改变角色颜色的不和谐机器人。它运行正常,但是,在运行此任务时,机器人无法注册其他命令或运行任何其他工作。 (当停止命令运行时它不会停止,因为它首先无法进入那里)。
我希望有人可以帮助解决这个问题。
所以这是代码的一部分:
[Group("rainbow")]
public class Rainbow : ModuleBase<SocketCommandContext>
{
public Boolean enabled;
[Command, RequireUserPermission(GuildPermission.ManageRoles)]
public async Task rainbowAsync(SocketRole role, int milliseconds)
{
if (milliseconds >= 500) {
enabled = true;
while (enabled)
{
Random rnd = new Random();
double id = rnd.NextDouble() * 7;
if (id < 1)
{
await role.ModifyAsync(a => a.Color = Discord.Color.Red);
}
else if (id < 2)
{
await role.ModifyAsync(a => a.Color = Discord.Color.Orange);
}
else if (id < 3)
{
await role.ModifyAsync(a => a.Color = Discord.Color.LightOrange);
}
else if (id < 4)
{
await role.ModifyAsync(a => a.Color = Discord.Color.Green);
}
else if (id < 5)
{
await role.ModifyAsync(a => a.Color = Discord.Color.Blue);
}
else if (id < 6)
{
await role.ModifyAsync(a => a.Color = Discord.Color.DarkBlue);
}
else if (id < 7)
{
await role.ModifyAsync(a => a.Color = Discord.Color.Purple);
}
await Task.Delay(milliseconds);
}
}
else { await ReplyAsync("Time value must be higher than 500ms"); }
}
[Command("stop"), RequireUserPermission(GuildPermission.ManageRoles)]
public async Task StopAsync()
{
enabled = false;
await ReplyAsync("Rainbow effect stopped");
}
}
答案 0 :(得分:-1)
正如亚历克斯在评论中提到的那样,
你的命令进入无限循环。
if (milliseconds >= 500) {
enabled = true;
while (enabled)
{
//Code
await Task.Delay(milliseconds);
}
}
这会将您的命令置于无限循环中,从而阻止其他命令触发。阻止其他命令在异步环境中触发的原因是因为Async仍然只是一个线程,而Discord.net调用命令的默认方式是await Command();
当等待异步调用时,它会阻止调用,直到任务完成。由于无限循环,你的任务永远不会完成。
有几种不同的方法可以解决这个问题,但我建议处理它的方法是安排重新着色。研究如何在每x个时间范围内安排任务。
作为一个例子
public class TimerTask
{
private readonly Timer _taskTimer;
public TimerTask(Action action, int interval = 10000)
{
_taskTimer = new Timer { AutoReset = true, Interval = interval };
_taskTimer.Elapsed += (_, __) => action();
}
public void Start() { _taskTimer.Start(); }
public void Stop() { _taskTimer.Stop(); }
}