In C #, I call a public API that has an API limit of 10 calls per second

In C #, I call a public API that has an API limit of 10 calls per second. The API has several methods, different users can call different methods at a time, therefore, there is a possibility that a "speed limit" can be achieved.

I have the following class structure:

public class MyServiceManager { public int Method1() { } public void Method2() { } public string Method3() { } } 

Several users can call different methods at the same time. How can I maintain a static call queue or task so that I can control all requests and entertain just 10 requests in one second

+7
multithreading c # task-parallel-library task
source share
1 answer

You can create TaskLimiter based on SemaphoreSlim

 public class TaskLimiter { private readonly TimeSpan _timespan; private readonly SemaphoreSlim _semaphore; public TaskLimiter(int count, TimeSpan timespan) { _semaphore = new SemaphoreSlim(count, count); _timespan = timespan; } public async Task LimitAsync(Func<Task> taskFactory) { await _semaphore.WaitAsync().ConfigureAwait(false); var task = taskFactory(); task.ContinueWith(async e => { await Task.Delay(_timespan); _semaphore.Release(1); }); await task; } public async Task<T> LimitAsync<T>(Func<Task<T>> taskFactory) { await _semaphore.WaitAsync().ConfigureAwait(false); var task = taskFactory(); task.ContinueWith(async e => { await Task.Delay(_timespan); _semaphore.Release(1); }); return await task; } } 

He will

  • wait for the semaphore "slot"
  • run a real task.
  • release the semaphore slot after a specified period of time when the real task ends.

Here is a usage example

 public class Program { public static void Main() { RunAsync().Wait(); } public static async Task RunAsync() { var limiter = new TaskLimiter(10, TimeSpan.FromSeconds(1)); // create 100 tasks var tasks = Enumerable.Range(1, 100) .Select(e => limiter.LimitAsync(() => DoSomeActionAsync(e))); // wait unitl all 100 tasks are completed await Task.WhenAll(tasks).ConfigureAwait(false); } static readonly Random _rng = new Random(); public static async Task DoSomeActionAsync(int i) { await Task.Delay(150 + _rng.Next(150)).ConfigureAwait(false); Console.WriteLine("Completed Action {0}", i); } } 
+8
source share

All Articles