HttpClient под нагрузкой игнорирует тайм-аут - PullRequest
0 голосов
/ 11 сентября 2018

При использовании 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 секунды.Я опубликую весь пример кода, если потребуется, но это должно быть легко воссоздать с тем, что я опубликовал сейчас.

...