2015-10-20 17 views
8

Sto utilizzando la classe HttpClient in .Net 4.5.2 framework. Sto facendo un PostAsync a un servizio web di terze parti. L'80% delle volte questo post funziona, il 20% delle volte la nostra risposta viene interrotta. In questa situazione si ottiene la seguente eccezione:System.Net.Http.HttpRequestException Errore durante la copia del contenuto in un flusso

System.Net.Http.HttpRequestException: errore durante la copia dei contenuti per un ruscello. ---> System.IO.IOException: impossibile leggere i dati dalla connessione di trasporto : una connessione esistente è stata forzatamente chiusa da l'host remoto. ---> System.Net.Sockets.SocketException: Una connessione esistente è stata chiusa forzatamente dall'host remoto su System.Net.Sockets.NetworkStream.BeginRead (Byte [] buffer, Int32 offset, Int32, AsyncCallback callback, Stato dell'oggetto) --- Fine della traccia dello stack di eccezioni interne --- a System.Net.Sockets.NetworkStream.BeginRead (Byte [] buffer, Int32 offset, Int32, AsyncCallback callback, Stato oggetto) al sistema . Net.FixedSizeReader.StartReading() a System.Net.Security._SslStream.StartFrameHeader (Byte tampone [], Int32 compensato, conteggio Int32, AsyncProtocolRequest asyncRequest) a System.Net.Security._SslStream.StartReading (Byte [] tampone , Int32 offset, int 32 conteggio, AsyncProtocolRequest asyncRequest) a System.Net.Security._SslStream.ProcessRead (Byte tampone [], Int32 compensato, conteggio Int32, AsyncProtocolRequest asyncRequest) a System.Net.TlsStream.BeginRead (Byte [] tampone, offset Int32 , Int32 dimensioni, AsyncCallback asyncCallback, oggetto asyncState) a System.Net.ConnectStream.BeginReadWithoutValidation (Byte [] tampone, offset Int32, Int32 dimensioni, AsyncCallback callback, stato oggetto) a System.Net.ConnectStream.BeginRead (Byte [] buffer, Int32 offset, Int32 dimensioni, callback Callbackback asincrono, stato oggetto) a System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead (Byte [] buffer, offset Int32, conteggio Int32, callback Callback asincrono, Object stato) a System.Net.Http.StreamToStreamCopy.StartRead()

Una successiva richiesta identica riesce. Non è una richiesta, possiamo riprovarci dato che l'attività è già stata effettuata. Quindi ci lascia in una situazione imbarazzante.

Questo è il mio codice:

using (var httpClient = new HttpClient()) 
{ 
    httpClient.DefaultRequestHeaders.Authorization = authorizationHeader; 
    HttpContent httpContent = new StringContent(someXml); 

    //Exception occurs on next line... 
    var response = await httpClient.PostAsync("https://thirdpartyendpoint", httpContent); 
    var responseXml = await response.Content.ReadAsStringAsync(); 
    //convert to Dto    
} 

Il servizio di terze parti stanno salvando con successo il record al loro database e non vedono alcuna eccezione evidenti alla loro estremità. Hanno notato che le richieste non riuscite in genere richiedevano più tempo (circa 18-30 secondi) per scrivere nel database rispetto alle richieste riuscite.

Grazie per il vostro aiuto

+0

sembra che ci sia un'operazione di blocco o cattivi indici nel loro database. Prova a profilare le query del database o monitorare i blocchi db. –

+0

Ciao Roman, nonostante il ritardo aggiuntivo, non sollevano un'eccezione nel loro codice e completano la risposta. Semplicemente non lo riceviamo. – jonho

+1

Controllerebbero il timeout della connessione HTTP dalla loro parte. –

risposta

10

abbiamo risolto questo problema con i cambiamenti 2 codice:

  1. Smaltire la httpResponseMessage e solo di lavoro con un semplice DTO

    using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage)) 
        { 
         return await CreateDto(httpResponseMessage); 
        } 
    
  2. downgrade alla versione da HTTP a v1.0

    var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(url)) 
    { 
        Version = HttpVersion.Version10, 
        Content = httpContent 
    }; 
    
    await client.SendAsync(httpRequestMessage); 
    

che ha l'effetto di aggiungere l'intestazione HTTP

Connection: close 

piuttosto che questo

Connection: keep-alive 
+0

Eventuali idee su come applicare HttpVersion a httpClient ottengono le richieste? – garenyondem

+1

var httpRequestMessage = new HttpRequestMessage (HttpMethod.Get, nuovo Uri (url)) { Versione = HttpVersion.Version10, Content = httpContent }; attende client.SendAsync (httpRequestMessage); dovrebbe farlo – jonho

+0

ha funzionato per me.grazie –

Problemi correlati