При использовании HttpClient (либо тот же, либо создание нового для каждого запроса или даже создание нового при каждом запросе) с таймаутом GetStringAsync увеличивается в зависимости от нагрузки на клиента.Вот пример кода.
public class AsyncTester
{
private readonly Dictionary<int, HttpClient> _httpClients = new Dictionary<int, HttpClient>();
public async void Test()
{
await WaitForTimeout(2);
}
public async Task WaitForTimeout(int seconds)
{
var client = GetClientWithTimeout(seconds);
var sw = new Stopwatch();
try
{
sw.Start();
var res = await client.GetStringAsync("https://19.38.249.96/?format=json"); //or any URL that will timeout
sw.Stop();
}
catch (Exception)
{
if (sw.IsRunning)
{
sw.Stop();
}
}
Console.WriteLine(sw.Elapsed.TotalMilliseconds);
}
private HttpClient GetClientWithTimeout(int timeoutSeconds)
{
if (_httpClients.ContainsKey(timeoutSeconds))
{
return _httpClients[timeoutSeconds];
}
else
{
var client = new HttpClient(new HttpClientHandler()) { Timeout = TimeSpan.FromSeconds(timeoutSeconds) };
_httpClients.Add(timeoutSeconds, client);
return client;
}
}
}
Теперь давайте создадим такой класс.Если мы вызываем Test()
в бесконечном цикле while, и там мы спим Thread.Sleep(10)
миллисекунды, веселье начинается.У первой пары запросов время ожидания OK составляет около 2 секунд, но все последующие - 2+ секунды, а через некоторое время они доходят до 10+ секунд.
Теперь я надеюсь, что делаю что-то не так, потому что мне нужноисключение тайм-аута, на которое я могу рассчитывать, и мне нужно, чтобы оно было примерно точным, я могу жить с ошибкой 50%, но с 500% немного глупо.
Имейте в виду, что (на моем ПК разработчика), когдаВы используете более длинный сон Thread.Sleep(70)
это намного ближе к 2 секундам, которые я хочу.Кроме того, если мы перейдем к допустим, скажем Thread.Sleep(200)
, это почти точно 2 секунды.Я опубликую весь пример кода, если потребуется, но это должно быть легко воссоздать с тем, что я опубликовал сейчас.