Ограничение по времени на исполнение асинхронных задач

Как я могу реализовать метод Execute, чтобы задачи стартовали не чаще, чем раз в секунду (одновременно они выполняться могут в любом количестве, но именно старт должен происходить не чаще 1 раза в секунду)

public class Program 
{
    public static async Task Main(string[] args)
    {
        var tasks = Enumerable.Range(0, 10).Select(x => MyTask()).ToArray();
        await Execute(tasks);
    }

    public static async Task MyTask()
    {
        Console.WriteLine("Task started");
        await Task.Delay(new Random().Next(2000));
        Console.WriteLine("Task stopped");
    }

    public static async Task Execute(Task[] tasks)
    {

    }
}

Ответы (1 шт):

Автор решения: Scrzii

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

public class Program
{
    public static async Task Main(string[] args)
    {
        var tasks = Enumerable.Range(0, 10).Select(x => MyTask(x));
        await Execute(tasks);
    }

    public static async Task MyTask(int id)
    {
        Console.WriteLine($"Task {id} started");
        await Task.Delay(new Random().Next(3000));
        Console.WriteLine($"Task {id} stopped");
    }

    public static async Task Execute(IEnumerable<Task> tasks)
    {
        var lastStart = DateTime.Now.AddDays(-1);
        var enumerator = tasks.GetEnumerator();
        var startedTasks = new List<Task>();
        while (true)
        {
            if (lastStart.AddSeconds(1) > DateTime.Now)
            {
                await Task.Delay(5);
                continue;
            }
            lastStart = DateTime.Now;
            if (!enumerator.MoveNext())
            {
                break;
            }

            startedTasks.Add(enumerator.Current);
        }

        Task.WaitAll(startedTasks.ToArray());
        Console.WriteLine("All tasks completed");
    }
}
→ Ссылка