Task.WhenAny with timeout expects more than timeout value

I have this code block:

var client = new TcpClient();
HttpRequestInfo.AddTimestamp("Connecting");
await Task.WhenAny(client.ConnectAsync(serverAddress, serverPort),
                   Task.Delay(TimeSpan.FromMilliseconds(300)));
HttpRequestInfo.AddTimestamp("Connected");
if(client.Connected){ ... }

Where HttpRequestInfo.AddTimestamp just writes the timestamp names with the stopwatch class.

In magazines, I sometimes see:

"Connecting":110ms - "Connected":747ms
"Connecting":35ms - "Connected":3120ms
"Connecting":38ms - "Connected":3053ms

I suggested that this approach will give me the opportunity to limit the connection to a timeout (300 ms). However, I see that this line of code sometimes (very rarely) runs longer than 300 ms. What is the reason for this behavior?

+4
source share
1 answer

docs :

This method depends on the system clock. This means that the delay time will be approximately equal to the resolution of the system clock if the delay argument is less than the resolution of the system clock, which is about 15 milliseconds on Windows systems.

, -, 15 300 , .

-, .
, - ConnectAsync , , Task.Delay, .

, , ConnectAsync:

var client = new TcpClient();
HttpRequestInfo.AddTimestamp("Launching ConnectAsync");
var connectAsyncTask = client.ConnectAsync(serverAddress, serverPort);
HttpRequestInfo.AddTimestamp("ConnectAsync launched");
HttpRequestInfo.AddTimestamp("Launching Delay");
var delayTask= Task.Delay(TimeSpan.FromMilliseconds(300));
HttpRequestInfo.AddTimestamp("Delay launched");
var firstTask = await Task.WhenAny(connectAsyncTask, delayTask);
if(firstTask == connectAsyncTask)
{ 
    HttpRequestInfo.AddTimestamp("Connected");
}
else
{
    HttpRequestInfo.AddTimestamp("Timeout");
}
+2

Source: https://habr.com/ru/post/1692614/


All Articles