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