Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I await a minimum amount of time?

I have an async C# method where I am getting an HTTP resource, and I am doing it in an infinite loop. However I don't want to hit the resource too quickly. My current code is:

HttpClient http = new HttpClient();
while (true) {
    // Long-poll the API
    var response = await http.GetAsync(buildUri());

    Console.WriteLine("Resp: " + response.ToString());
    Console.WriteLine("CONTENT:");
    Console.WriteLine(await response.Content.ReadAsStringAsync());
}

However, I want to be able to make sure I don't make an HTTP request more often than once per 10 seconds. So I want to start a 10 second timer at the beginning of the loop, and at the end say "await the completion of the 10 second timer". Is there a way to do this in C#.NET?

like image 556
Jez Avatar asked Nov 07 '18 00:11

Jez


People also ask

How long does await wait for?

Basically, forever. Also the await doesn't hold up anything.

What happens if you dont use await?

If you don't await the task or explicitly check for exceptions, the exception is lost. If you await the task, its exception is rethrown. As a best practice, you should always await the call.

Why you should not use async void?

Async void methods can wreak havoc if the caller isn't expecting them to be async. When the return type is Task, the caller knows it's dealing with a future operation; when the return type is void, the caller might assume the method is complete by the time it returns.

What is await keyword in C#?

The await operator suspends evaluation of the enclosing async method until the asynchronous operation represented by its operand completes. When the asynchronous operation completes, the await operator returns the result of the operation, if any.


1 Answers

At the simplest:

while (true) {
    var rateLimit = Task.Delay(TimeSpan.FromSeconds(10));
    // ...await your http/whatever
    await rateLimit;
}

The await rateLimit will complete immediately if the http work took over the 10 seconds.

However, you may choose to compare the times before and after the http work, to see if you even need to wait; more like:

while (true) {
    var timeBefore = ...
    // ...await your http/whatever
    var timeAfter = ...
    // ... calculate time left
    if (timeLeft > TimeSpan.Zero) await Task.Delay(timeLeft);
}

This avoids the plumbing needed for Task.Delay in the scenarios where it would complete immediately.

like image 116
Marc Gravell Avatar answered Nov 15 '22 08:11

Marc Gravell