HttpClient è sicuro da usare contemporaneamente?


151

In tutti gli esempi che posso trovare sugli utilizzi di HttpClient, viene utilizzato per chiamate una tantum. Ma cosa succede se ho una situazione client persistente, in cui diverse richieste possono essere fatte contemporaneamente? Fondamentalmente, è sicuro chiamare client.PostAsync2 thread contemporaneamente contro la stessa istanza di HttpClient.

Non sto davvero cercando risultati sperimentali qui. Come esempio funzionante potrebbe essere semplicemente un colpo di fortuna (e persistente), e un esempio errato può essere un problema di configurazione errata. Idealmente sto cercando una risposta autorevole alla domanda sulla gestione della concorrenza in HttpClient.


2
Leggi anche questa domanda per ulteriori informazioni su come utilizzarlo HttpCliente smaltirlo correttamente : stackoverflow.com/questions/15705092/…
Mani Gandham,

Risposte:


152

Secondo MSDN , da .NET 4.5 I seguenti metodi di istanza sono thread-safe (grazie a @ischell):

CancelPendingRequests
DeleteAsync
GetAsync
GetByteArrayAsync
GetStreamAsync
GetStringAsync
PostAsync
PutAsync
SendAsync

3
Sì, non ero sicuro di quello, poiché sembra essere un avviso standard su tutto su MSDN (e ricordo di aver letto alcuni blog MSDN su come a volte quell'avviso è sbagliato, poiché viene applicato ciecamente a tutto).
Alex K,

3
Questo è sbagliato; nella sezione commenti della pagina MSDN che hai collegato, dice che GetAsync, PostAsync, ecc. sono tutti thread-safe.
Ischell,

4
@ischell: posso assicurarti che il paragrafo in questione non era presente al momento della discussione di questo problema.
Marcel N.

7
Quindi Microsoft ha progettato HttpClient in modo che sia riutilizzabile, ma la classe ha i dati di istanza per le intestazioni: client.DefaultRequestHeaders.Accept.Add (...);
termina l'

8
In ritardo, ma volevo commentare su @cwills. DefaultRequestHeaders sono proprio questi, i valori predefiniti. Se vuoi intestazioni diverse su una base di richiesta, puoi creare un nuovo StringContent (), impostare intestazioni aggiuntive su quello, quindi usare il sovraccarico che richiede URI e HttpContent.
Ryan Anderson,

92

Ecco un altro articolo di Henrik F. Nielsen su HttpClient in cui dice:

" L'HttpClient predefinito è il modo più semplice in cui è possibile iniziare a inviare richieste. Un singolo HttpClient può essere utilizzato per inviare tutte le richieste HTTP desiderate contemporaneamente, quindi in molti scenari è possibile creare un solo HttpClient e utilizzarlo per tutte le richieste " .


13
Che dire se il nome utente e la password possono cambiare tra i thread? questo è quello di cui non riesco a trovare nessuno che parli
Nicholas DiPiazza,

1
@NicholasDiPiazza: con che frequenza cambia? Se esiste un set noto di coppie utente / password, è possibile creare un pool di istanze HttpClient.
Marcel N.

sì, è quello che ho finito per fare
Nicholas DiPiazza il

2
Si noti che il riutilizzo dello stesso HttpClient per tutte le richieste potrebbe comportare problemi di DNS non aggiornati: github.com/dotnet/corefx/issues/11224 .
Ohad Schneider,

1
@OhadSchneider Se credi che il problema sia limitato al core .net. È possibile risolvere il problema con .net 4 iniettando un HttpClientHandler personalizzato nel costruttore HttpClient quindi impostando "ConnectionLeaseTimeout". Tuttavia, se non vengono inviate richieste all'endpoint per 100 secondi, la connessione si aggiornerà da sola. override protetto Attività <HttpResponseMessage> SendAsync (richiesta HttpRequestMessage, CancelToken notificationToken) {var sp = ServicePointManager.FindServicePoint (request.RequestUri); sp.ConnectionLeaseTimeout = 100 * 1000; }
Timothy Gonzalez,

17

Trovato un post sul forum MSDN di Henrik F. Nielsen (uno dei principali architetti di HttpClient).

Riepilogo rapido:

  • Se hai richieste correlate (o che non ti riguardano), utilizzare lo stesso HttpClient ha molto senso.
  • In generale, consiglierei di riutilizzare le istanze di HttpClient il più possibile.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.