When a user takes a certain action a call (get) to a web service is made. The service doesn't allow for calls more frequent than once per second. I was thinking I could use Task.Delay to control this so that subsequent calls are made at least one second apart in time but it doesn't seem to work as expected. The pseudo-code looks like this:
public async void OnUserAction()
{
var timeUntilPreviousCallWillBeOrWasMade = 1000ms - (Now - previousWaitStartTime);
var timeToWaitBeforeThisCallShouldBeMade = Max(0, timeUntilPreviousCallWillBeOrWasMade + 1000ms);
previousWaitStartTime = Now;
await Task.Delay(timeToWaitBeforeThisCallShouldBeMade);
MakeCallToWebService();
}
Calls and contiunations are done on same thread (as reported by Environment.CurrentManagedThreadId). The problem is that if there's a quick succession of invocations of this method the passed time between calls to the web service is less than 1s. I've either done a silly mistake or I don't fully understand Task.Delay (or both of the above). Any hints?
Can you use Thread.Sleep(millisecondsTimeout) at msdn?
I suggest you to use that.
It would appear that your problem happens when a request is queued up when another one is already waiting. Here's my take on your pseudo code:
And the output:
You should really be using the right tool for the job. How about a
SemaphoreSlim
?EDIT:
MakeThrottledCall
no longer returnsTask
as per svick's comment.