2013-05-23 4 views
4

У меня есть приложение веб-API ASP.NET, размещенное в веб-роли Windows Azure. Целью этого приложения является прокси-запрос Http для других конечных точек с поддержкой сети, таких как ретрансляция служебной шины и возврат их ответа.HttpClient.SendAsync HttpException: Клиент отключен

Иногда наше приложение выдает исключение при отправке запроса со значительной полезной нагрузкой (> 5 МБ). Это может произойти 1 из 20 запросов с большой полезной нагрузкой.

Сведения об исключении: System.AggregateException: Произошла одна или несколько ошибок: . ---> System.Web.HttpException: клиент отключен.
на System.Web.Hosting.IIS7WorkerRequest.EndRead (IAsyncResult AsyncResult) в System.Web.HttpBufferlessInputStream.EndRead (IAsyncResult AsyncResult) в System.Net.Http.StreamToStreamCopy.BufferReadCallback (IAsyncResult мп) --- Конец трассировки стека внутренних исключений --- ---> (Внутреннее исключение # 0) System.Web.HttpException (0x800703E3): клиент отключен. на System.Web.Hosting.IIS7WorkerRequest.EndRead (IAsyncResult AsyncResult) в System.Web.HttpBufferlessInputStream.EndRead (IAsyncResult AsyncResult) в System.Net.Http.StreamToStreamCopy.BufferReadCallback (IAsyncResult ар) < ---; TraceSource 'w3wp.exe' event

Мы отправляем эти запросы Http с использованием System.Net.HttpClient в .NET 4.5.

public class ProxyController : ApiController 
{ 
    private static readonly HttpClient HttpClient = new HttpClient(); 
    private static readonly Uri BaseUri = new Uri("http://webendpoint.com"); 

    public HttpResponseMessage Post() 
    { 
     var newUri = new Uri(BaseUri, Request.RequestUri.PathAndQuery); 
     var request = new HttpRequestMessage(HttpMethod.Post, newUri) 
       { 
        Content = this.Request.Content 
       }; 

     var task = HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); 
     task.Wait(); 
     var response = task.Result; 
     return new HttpResponseMessage(response.StatusCode) 
     { 
      Content = new PushStreamContent((stream, content, ctx) => 
      { 
       var tempStream = response.Content.ReadAsStreamAsync().Result; 
       tempStream.CopyToAsync(stream).Wait(); 
       stream.Flush(); 
       stream.Close(); 
      }) 
     }; 
    } 
} 

Любые мысли о том, что может вызвать эту проблему?

+0

Трудно помочь вам отладить этот код, поскольку вы должны его записать из памяти, потому что он полон ошибок. Тем не менее, первое, что я бы рекомендовал, если вы действительно создаете просто прокси, - это просто использовать DelegatingHandler и не беспокоиться об ApiController. –

+0

Справедливая точка зрения, я не делал вам никаких выгод с этим кодом. Моя вина. Обновлено. –

ответ

1

Попробуйте вернуть версию задачи, а затем замените код синхронизации на асинхронный. Больше нет «.Results», вместо этого используйте ключевое слово «ожидание» и поместите ключевое слово «asyc» в свой метод. Что-то вроде этого:

public class ProxyController : ApiController 
{ 
    private static readonly HttpClient HttpClient = new HttpClient(); 
    private static readonly Uri BaseUri = new Uri("http://webendpoint.com"); 

    public async Task<HttpResponseMessage> Post() 
    { 
     var newUri = new Uri(BaseUri, Request.RequestUri.PathAndQuery); 
     var request = new HttpRequestMessage(HttpMethod.Post, newUri) 
     { 
      Content = Request.Content 
     }; 

     var response = await HttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); 

     return new HttpResponseMessage(response.StatusCode) 
     { 
      Content = new PushStreamContent(async (stream, content, ctx) => 
      { 
       var tempStream = await response.Content.ReadAsStreamAsync(); 
       await tempStream.CopyToAsync(stream); 
       stream.Flush(); 
       stream.Close(); 
      }) 
     }; 
    } 
}