如何在不影响他人的情况下让它运行?

时间:2018-04-30 13:19:12

标签: c# discord.net

所以,我正在制作一个能够在一定时间后改变角色颜色的不和谐机器人。它运行正常,但是,在运行此任务时,机器人无法注册其他命令或运行任何其他工作。 (当停止命令运行时它不会停止,因为它首先无法进入那里)。

我希望有人可以帮助解决这个问题。

所以这是代码的一部分:

[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");
    }
}

1 个答案:

答案 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(); }
}