Большое количество запросов и тупиковых ситуаций в HttpClient (C#) - PullRequest
0 голосов
/ 29 февраля 2020

У меня есть приложение WPF. Одна из его основных задач - отправка запросов POST и получение ответов. До недавнего времени все работало нормально. Тем не менее, приложение развивается, я реализовал новые функции, и оказалось, что я, вероятно, отправляю слишком много запросов.

У меня только один экземпляр браузера. Моя браузерная реализация наследуется от класса HttpClient и содержит следующий метод:

public async Task<HttpResponseMessage> DoPostRequest(string path, IEnumerable<KeyValuePair<string, string>> data)
        {
            var urlRequest = this.BaseUrl + path;
            var requestContent = new FormUrlEncodedContent(data);

            HttpResponseMessage responseMessage = null;
            try
            {
                responseMessage = await base.PostAsync(urlRequest, requestContent);
            }
            catch (Exception ex)
            {
                if (responseMessage == null)
                {
                    responseMessage = new HttpResponseMessage();
                }
                responseMessage.StatusCode = HttpStatusCode.InternalServerError;
                responseMessage.ReasonPhrase = string.Format("RestHttpClient.SendRequest failed: {0}", ex);
            }

            return responseMessage;
        }

Если я забочусь о ответе (и в большинстве случаев так и есть), я использую следующий метод:

        public async Task<string> DoPostRequestAndReadContent(string path,  IEnumerable<KeyValuePair<string, string>> data)
        {
            var request = await this.DoPostRequest(path, data);
            return await request.Content.ReadAsStringAsync();
        }

При реализации своего решения я предложил следующий поток: { ссылка }


Использование : я использую описанные выше методы в следующих путь:

var response = this.DoPostRequestAndReadContent("/api/doSomething", data).Result;

Задача : я использую вышеупомянутый класс в разных местах проекта. Долгое время он работал нормально, но теперь время от времени возникает проблема. Количество запросов, которые я отправляю, недавно увеличилось. В настоящее время я отправляю от нескольких до дюжины запросов в секунду. Приложение отправляет их, сервер получает их, но Я не получаю ответ .

Возможная причина : я читал об этой проблеме, и многие люди указывают что источником проблемы может быть тупик . Поскольку при чтении ответа на запрос я использую Result, мой код больше не является асинхронным. Тем не менее, я не знаю, как еще я мог прочитать контент, полученный от API. Метод DoPostRequestAndReadContent возвращает мне Task<string> объект.

Таким образом, я думаю, что использование .Result неизбежно . Я ошибаюсь? Может быть ...

Я хотел бы попросить вас помочь в решении этой проблемы. Я искал похожие темы, но ни одна из них мне не помогла. Я лишь немного изменил реализацию моих методов (вы могли видеть их выше), но это не решило проблему. Запросы отправляются, но ответы не читаются.

1 Ответ

1 голос
/ 29 февраля 2020

Если вы предоставите больше контекста, это может помочь читателям понять, как вы используете эту функцию в своем приложении, но решение, которое имеет смысл, заключается в await ее. async/await вирусный. В конечном итоге вы распространяете его по всему стеку вызовов.

Просто чтобы прояснить ситуацию, await позволяет существующему потоку отключать go и делать другие вещи, а затем возвращаться, когда вы .Result, это как вызов await, но синхронизация и блокировка.

var response = await this.DoPostRequestAndReadContent("/api/doSomething", data);
...