Limiter le nombre de tâches dans Task.Factory.Start par seconde

J’ai lu plusieurs articles sur la limitation du nombre de tâches à la fois ( System.Threading.Tasks – Limiter le nombre de tâches simultanées est un bon choix).

Cependant, je dois limiter le nombre de tâches à la seconde – seulement X nombre de tâches à la seconde? Y a-t-il un moyen facile d’accomplir cela?

J’ai pensé créer un ConcurrentDictionary, la clé étant la seconde actuelle et la seconde le compte jusqu’à présent. Le fait de vérifier si nous sums à 20 pour la seconde actuelle, puis arrêtez. Cela semble sous-optimal.

Je préfère faire quelque chose comme faire une tâche tous les 1/20. Des pensées?

Je pense que cela peut être un sharepoint départ. L’exemple ci-dessous crée 50 tâches (exécution de 5 tâches / s).

Cela ne bloque pas le code qui crée les tâches. Si vous souhaitez bloquer l’appelant jusqu’à ce que toutes les tâches aient été planifiées, vous pouvez utiliser Task.Delay((int)shouldWait).Wait() dans QueueTask

 TaskFactory taskFactory = new TaskFactory(new TimeLimitedTaskScheduler(5)); for (int i = 0; i < 50; i++) { var x = taskFactory.StartNew(() => DateTime.Now.Second) .ContinueWith(t => Console.WriteLine(t.Result)); } Console.WriteLine("End of Loop"); 

 public class TimeLimitedTaskScheduler : TaskScheduler { int _TaskCount = 0; Stopwatch _Sw = null; int _MaxTasksPerSecond; public TimeLimitedTaskScheduler(int maxTasksPerSecond) { _MaxTasksPerSecond = maxTasksPerSecond; } protected override void QueueTask(Task task) { if (_TaskCount == 0) _Sw = Stopwatch.StartNew(); var shouldWait = (1000 / _MaxTasksPerSecond) * _TaskCount - _Sw.ElapsedMilliseconds; if (shouldWait < 0) { shouldWait = _TaskCount = 0; _Sw.Restart(); } Task.Delay((int)shouldWait) .ContinueWith(t => ThreadPool.QueueUserWorkItem((_) => base.TryExecuteTask(task))); _TaskCount++; } protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { return base.TryExecuteTask(task); } protected override IEnumerable GetScheduledTasks() { throw new NotImplementedException(); } }