1

В веб-запросе я хочу сделать вызов на другой сервер с помощью Microsoft HttpClient. Я использую MVC4 (размещен в IIS), а lock-windsor - как контейнер IOC. Я прочитал, что HttpClient предназначен для работы во время серверных вызовов, и мой вопрос заключается в том, как я должен это реализовать.Образ жизни HttpClient в MVC4 с использованием lock-windsor

я придумал несколько вариантов:

  1. игнорировать тот факт, что HttpClient предназначен для нескольких вызовов и создать новую каждый раз, когда мне нужно один.
  2. Создайте объект Singleton (образ жизни в замке), который хранит HttpClient между вызовами. Есть ли риск с этим? Будет ли производительность плохим, если несколько веб-запросов используют один и тот же HTTP-клиент?

Есть ли лучший образец для этого?

ответ

2

Я бы использовал LifestyleTransient для создания нового для каждого запроса. Это безопаснее, если вы не уверены, что класс может работать как одиночный.

Это также неплохая идея напрямую зависеть от абстракции (интерфейса), а не от HttpClient, если вы не уверены, что этот класс никогда не будет использоваться отдельно от запросов HTTP. Даже тогда это может упростить модульное тестирование. Это одно из больших преимуществ использования Windsor или другого контейнера DI. В противном случае вы не сможете воспользоваться преимуществами только для создания HttpClient непосредственно в своем классе.


Обновление. Я просмотрел и нашел this answer, указав, что HttpClient следует использовать повторно для данного API. Это очень высоко, и я не вижу никакого отношения к опыту (или иначе), поэтому я собираюсь ссылаться на него, когда вы делаете некоторое краткосрочное развитие.

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

+0

Означает ли это, что 'HttpClient' может обрабатывать сразу несколько вызовов (из разных потоков) с хорошей производительностью? Если вызовы выполняются в блокировке, функция будет плохой, и в этом случае может быть хорошей идеей реализовать пул 'HttpClient' – jabocop

+0

. Это то, что говорит дискуссия. Фактически, это говорит о том, что это не может привести к проблемам с производительностью. У меня нет опыта с большим объемом, поэтому я предложил заблудиться на стороне осторожности, но у меня есть работа такого характера, поэтому я буду продолжать искать что-то окончательное. Но ответ, опросы и комментарии делают для этого хороший аргумент. –

+0

Спасибо большое за ваши комментарии. Я буду использовать HttpClient как одноэлементный. Я также нашел [документацию] (https://msdn.microsoft.com/en-us/library/system.net.http.httpclient%28v=vs.110%29.aspx) для HttpClient из Microsoft (обновлено для. Net Framwork 4.5 и 4.6), что указывает на то, что куча методов на самом деле является потокобезопасной. – jabocop

0

По умолчанию, если вы создаете новый экземпляр HttpClient для каждого вызова, каждый вызов будет создавать новое TCP-соединение, и это приведет к задержке и уменьшению пропускной способности. Если вы хотите иметь новый экземпляр HttpClient, потому что на нем есть данные для каждого вызова, тогда вы можете иметь одноэлементный HttpClientHandler, передать его в httpClient ctor и поделиться своими TCP-соединениями по экземплярам HttpClient.

Скотт, здесь три подхода мы использовали эту работу. Я надеюсь, что это поможет, я новичок в stackoverflow, поэтому не могу разместить более двух ссылок.

1) Просто статические/одноточечно HTTPClient и передавать любые за каждый вызов заголовки с HttpRequestMessage, как описано here

2) имеют статический/одноточечно WebRequest | HttpClientHandler, и передать в HttpClient ctor с disposeHandler набором к ложному.

3) В некоторых случаях у нас была библиотека инструментов DelegatingHandler, которая должна была быть удалена после каждого вызова HttpClient. Таким образом, мы создали WebRequestHandler, который ничего не делает в Dispose(), как показано ниже, передал его делегатскому агентству ctor, а затем передал делегирование Handler на httpClient ctor с установкой disposeHandler на false.

public class LongLivedWebRequestHandler : WebRequestHandler 
{ 
    public override void Dispose() 
    { 
     // Do nothing... 
    } 
} 
+0

Можете ли вы сослаться на любую документацию или примеры? Это звучит как то, о чем мне нужно знать. Спасибо –

+0

Да, документация была немного тонкой. Мы обнаружили, что он звонит из одного классического веб-сервиса Azure в другой, и разница между нашей исходящей и входящей задержкой составляет ~ 100 мс, я думаю. Совместное использование долговременного WebRequest | HttpClientHandler, штраф за пересылку снизился до ~ 20 мс. Есть три примера, которые работают. – AlejandroOeste