3

I have a method that sends request to my server every second.

public async Task StartRequestProcess(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCanecllationRequested)
    {
       var result = await GetDataFromServerAsync();
       await Task.Delay(1000, stoppingToken);
    }
}

But my GetDataFromServerAsync() method takes 10 or 15 seconds sometimes.

What does in this time (10 or 15 seconds)?

Will process wait until complete long requests? Or will new requests send every second without wait?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
barteloma
  • 6,403
  • 14
  • 79
  • 173

3 Answers3

8

I have a method that sends a request to my server every second.

No, you do not. Please do not open questions with false statements; it makes them hard to answer!

Your workflow is:

  • Request data
  • Wait for the data to arrive -- that's what asynchronously wait means. await is asynchronously wait.
  • Once the data has arrived, pause for a second, again, asynchronously
  • Repeat.

That is NOT the workflow "send a request every second". That is the workflow "send a request one second after the last request succeeded".

What does in this time (10 or 15 seconds)?

Asynchronously waits. You said to asynchronously wait until the data was available, and that's what it does. During the asynchronous wait other tasks can be scheduled to execute on the thread.

Will the workflow wait until the long request is completed?

Yes. It will wait asynchronously. Again, that's what await means. It means asynchronously wait.

Will new requests send every second without wait?

No. You said to wait until the data was received and then pause for one second, so that's what happens.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • You may want to elaborate somewhat the difference between "synchronous" and "asynchronous" waiting because one have to read the answer very carefully to notice that there is difference between them. – Joker_vD Mar 26 '20 at 22:46
  • 1
    @Joker_vD: I take your point but I'm not intending this to be a tutorial on how asynchrony works; if the reader is unclear on what the difference is between asynchronous waiting and synchronous waiting, then they need to do some reading on their own to get educated about what the feature is. – Eric Lippert Mar 26 '20 at 22:50
1

The whole idea of TAP (task Async pattern) is that a single thread can service lots of things "simultaneously" because it can go back to what it was doing before, any time that an await is in progress. This is why async marking on methods tends to be on every method right the way down in a hierarchy from the first point that the code you write (your controller Get method for example) through every method you call, right the way to where you need to wait something like db or network IO.

Encountering await is a bit like throwing an uncaught exception- control flow goes right the way back up the entire stack of methods that is your code, and out of the top, back to whatever was going on before, outside of your code. The difference between a thrown exception and an awaiting state machine is that when the task being awaited is done, the thread that went off to do other things will come back to where the await is and continue on from there

What it was doing before is highly contextual - in your case it's probably "waiting for a TCP client to connect and send some data"

Now, in your your code the thread goes back to what it was doing before- you say it takes 15 seconds so the thread will busy itself with other things for 15 seconds, then it will come back and wait for your 1000ms task to complete, then it will loop round and issue another request. In practice what this means is that every 16 seconds your code will make a request; not the request every second that you were hoping for. Use a timer

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
0

When you call await GetDataFromServerAsync(), execution of your method will resume once the asynchronous operation finishes, e.g., after 10 to 15 seconds. Only then will you wait asynchronously for another second.

Thomas Barnekow
  • 2,059
  • 1
  • 12
  • 21