как я могу позволить этому работать без ущерба для других? - PullRequest
0 голосов
/ 30 апреля 2018

Итак, я делал бот-диск, который мог бы менять цвет роли через определенный промежуток времени. он работал правильно, однако бот не может зарегистрировать другие команды или выполнить какую-либо другую работу во время выполнения этой задачи. (он не остановится, когда будет запущена команда остановки, поскольку он не смог войти туда в первую очередь).

Я надеялся, что кто-то здесь сможет помочь решить эту проблему.

так вот часть кода:

[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 голосов
/ 25 мая 2018

Как отметил Алекс в своем комментарии,

Ваша команда входит в бесконечный цикл.

if (milliseconds >= 500) {
    enabled = true;       
    while (enabled)
    {
        //Code
        await Task.Delay(milliseconds);
    }
}

Это помещает вашу команду в бесконечный цикл, который предотвращает запуск других команд. Причина, по которой это предотвращает запуск других команд в среде Async, заключается в том, что Async по-прежнему является просто одним потоком, а Discord.net по умолчанию вызывает вашу команду: await Command();

Когда ожидается асинхронный вызов, он блокирует вызов до завершения Задачи. Ваша задача никогда не будет выполнена из-за бесконечного цикла.

Есть несколько разных способов справиться с этим, но я бы посоветовал справиться с этим - запланировать перекрашивание. Посмотрите, как планировать выполнение задач на каждом временном интервале.

Как пример

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