2015-10-20 21 views
8

我在.Net 4.5.2框架中使用了HttpClient類。 我正在對第三方Web服務進行PostAsync。這篇文章有80%的時間工作,20%的時間我們的反應被縮短了。在這種情況下,我們得到以下異常:System.Net.Http.HttpRequestException將內容複製到流時出錯

System.Net.Http.HttpRequestException:錯誤,同時複製內容 流。 ---> System.IO.IOException:無法從 傳輸連接中讀取數據:現有連接被遠程主機強制關閉了 。 ---> System.Net.Sockets.SocketException:現有的 連接被遠程主機強制關閉,位於 System.Net.Sockets.NetworkStream.BeginRead(Byte [] buffer,Int32 offset,Int32 size,AsyncCallback callback,對象狀態)--- End 內部異常堆棧跟蹤---在 System.Net.Sockets.NetworkStream.BeginRead(Byte []緩衝區,Int32 偏移量,Int32大小,AsyncCallback回調,對象狀態)在 系統。 System.Net.Security._SslStream.StartReading(Byte [] buffer)Net.FixedSizeReader.StartReading()at System.Net.Security._SslStream.StartFrameHeader(Byte [] buffer,Int32 offset,Int32 count,AsyncProtocolRequest asyncRequest) ,Int32 offset,Int System.Net.Security._SslStream.ProcessRead(Byte []緩衝區,Int32 偏移量,Int32計數,AsyncProtocolRequest asyncRequest),位於 System.Net.TlsStream.BeginRead(Byte [] buffer,Int32 offset ,的Int32 大小,的AsyncCallback的AsyncCallback,對象asyncState)在 System.Net.ConnectStream.BeginReadWithoutValidation(字節[]緩衝液, 的Int32偏移的Int32大小,AsyncCallback的回調,對象狀態)在 System.Net.ConnectStream.BeginRead(字節[]緩衝區,Int32偏移,Int32 大小,AsyncCallback回調,對象狀態)在 System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.BeginRead(Byte [] 緩衝區,Int32偏移量,Int32計數,AsyncCallback回調,對象 狀態)在System.Net.Http.StreamToStreamCopy.StartRead()

隨後相同的請求成功。 這不是我們可以重試的請求,因爲業務已經被放置。所以它讓我們處於一個尷尬的境地。

這是我的代碼:

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    
} 

第三方服務成功地保存記錄自己的數據庫,並沒有看到他們到底有什麼明顯的例外。他們確實注意到,失敗的請求通常需要更長的時間(大約18-30秒)才能寫入數據庫,而不是成功的請求。

謝謝你們的幫助

+0

的效果似乎是有阻塞的操作或在它們的數據庫中的壞的索引。嘗試配置數據庫查詢或監視數據庫鎖。 –

+0

嗨Roman,儘管有額外的延遲,他們並沒有在他們的代碼中引發異常,他們完成了迴應。我們只是不收到它。 – jonho

+1

他們會檢查HTTP連接超時。 –

回答

10

我們解決了這個問題具有2碼的變化:

  1. 處置的httpResponseMessage的,只是一個簡單的DTO

    using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage)) 
        { 
         return await CreateDto(httpResponseMessage); 
        } 
    
  2. 降級版本工作的HTTP到v1。0

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

其具有增加該HTTP頭

Connection: close 

而非此

Connection: keep-alive 
+0

關於如何將HttpVersion應用於httpClient get請求的任何想法? – garenyondem

+1

var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get,new Uri(url)) { Version = HttpVersion.Version10, Content = httpContent }; 等待client.SendAsync(httpRequestMessage);應該這樣做 – jonho

+0

爲我工作,謝謝 –