HttpClient peut-il être utilisé en toute sécurité simultanément?

151

Dans tous les exemples que je peux trouver des usages de HttpClient, il est utilisé pour des appels ponctuels. Mais que se passe-t-il si j'ai une situation client persistante, où plusieurs demandes peuvent être effectuées simultanément? Fondamentalement, est-il sûr d'appeler client.PostAsync2 threads à la fois contre la même instance de HttpClient.

Je ne cherche pas vraiment de résultats expérimentaux ici. Un exemple de travail pourrait simplement être un coup de chance (et un exemple persistant), et un exemple défaillant peut être un problème de mauvaise configuration. Idéalement, je recherche une réponse faisant autorité à la question de la gestion de la concurrence dans HttpClient.

Alex K
la source
2
Lisez également cette question pour plus d'informations sur la façon de l'utiliser HttpClientet de s'en débarrasser correctement : stackoverflow.com/questions/15705092/…
Mani Gandham

Réponses:

152

Selon MSDN , depuis .NET 4.5 Les méthodes d'instance suivantes sont thread-safe (merci @ischell):

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync
Marcel N.
la source
3
Oui, je n'étais pas sûr de celui-là, car il semble être un avertissement standard sur tout sur MSDN (et je me souviens avoir lu certains blogs MSDN sur le fait que cet avertissement est parfois erroné, car il est appliqué aveuglément à tout).
Alex K
3
C'est faux; dans la section des remarques de la page MSDN que vous avez liée, il est dit que GetAsync, PostAsync, etc. sont tous thread-safe.
ischell
4
@ischell: Je peux vous assurer que le paragraphe en question n'était pas là au moment où cette question a été discutée.
Marcel N.3
7
Microsoft a donc conçu HttpClient pour qu'il soit réutilisable, mais la classe a des données d'instance pour les en-têtes: client.DefaultRequestHeaders.Accept.Add (...);
cwills
8
En retard, mais je voulais faire un commentaire sur @cwills. DefaultRequestHeaders ne sont que cela, les valeurs par défaut. Si vous voulez des en-têtes différents par demande, vous pouvez créer un nouveau StringContent (), définir des en-têtes supplémentaires à ce sujet, puis utiliser la surcharge qui prend URI et HttpContent.
Ryan Anderson
92

Voici un autre article d'Henrik F. Nielsen sur HttpClient où il dit:

" Le HttpClient par défaut est le moyen le plus simple de commencer à envoyer des requêtes. Un seul HttpClient peut être utilisé pour envoyer autant de requêtes HTTP que vous le souhaitez simultanément . Dans de nombreux scénarios, vous pouvez simplement créer un HttpClient, puis l'utiliser pour toutes vos requêtes. . "

muruge
la source
13
Et si le nom d'utilisateur et le mot de passe peuvent changer entre les threads? c'est ce dont je ne trouve personne qui parle
Nicholas DiPiazza
1
@NicholasDiPiazza: à quelle fréquence change-t-il? S'il existe un ensemble connu de paires utilisateur / mot de passe, vous pouvez créer un pool d'instances HttpClient.
Marcel N.
oui c'est ce que j'ai fini par faire
Nicholas DiPiazza
2
Notez que la réutilisation du même HttpClient pour toutes vos demandes peut entraîner des problèmes DNS obsolètes: github.com/dotnet/corefx/issues/11224 .
Ohad Schneider
1
@OhadSchneider Si je crois que ce problème est limité au noyau .net. Vous pouvez résoudre le problème avec .net 4 en injectant un HttpClientHandler personnalisé dans le constructeur HttpClient puis en définissant le "ConnectionLeaseTimeout". Cependant, si aucune demande n'est envoyée au point de terminaison pendant 100 secondes, la connexion s'actualise d'elle-même. protection de remplacement Task <HttpResponseMessage> SendAsync (requête HttpRequestMessage, CancellationToken annulationToken) {var sp = ServicePointManager.FindServicePoint (request.RequestUri); sp.ConnectionLeaseTimeout = 100 * 1000; }
Timothy Gonzalez
17

J'ai trouvé un message sur le forum MSDN par Henrik F. Nielsen (l'un des principaux architectes de HttpClient).

Résumé rapide:

  • Si vous avez des demandes qui sont liées (ou qui ne marchent pas l'une sur l'autre), l'utilisation du même HttpClient a beaucoup de sens.
  • En général, je recommanderais de réutiliser autant que possible les instances HttpClient.
Alex K
la source