2014-12-22 2 views
4

После прочтения/поиска по сайту HttpClient у меня создается впечатление, что этот компонент не подходит для загрузки больших файлов или содержимого в службы REST.Недостаток HttpClient при отправке больших файлов/содержимого?

  1. Похоже, что если загрузка занимает больше установленного таймаута, передача не удастся. Имеет ли это смысл? Что означает этот тайм-аут?

  2. Получение информации о ходе работы кажется трудным или требует надстроек.

Итак, мои вопросы: возможно ли решить эти два вопроса без особых проблем? В противном случае, какой лучший подход при работе с большим содержимым и службами REST?

+0

Не может быть конечной точки отдыха, которая может получить поток вместо большого файла. – Saravanan

+0

Существует таймаут запроса, который прервет запрос, если его достигнуто, что возможно, если вы отправляете большой файл. Вам может быть лучше с HttpWebRequest, где вы можете установить тайм-аут. – Andy

+2

@ Andy, вы также можете установить тайм-аут с помощью HttpClient; но к какой ценности вы должны его установить? Вы не знаете, как это продвигается, сколько времени потребуется, чтобы загрузить файл ... Я написал [статью] (http://www.thomaslevesque.com/2014/01/14/tackling-timeout-issues-when -uploading-large-files-with-httpwebrequest /) об этой проблеме при использовании 'HttpWebRequest', но, к сожалению, решение, которое я нашел, не относится к' HttpClient'. –

ответ

0
  1. Да, если загрузка занимает больше времени, чем TimeOut, загрузка не удастся. Это ограничение HttpClient. Наиболее надежным решением этой проблемы является тот, который Thomas Levesque имеет written an article about и связан в его комментариях к вашему вопросу. Вы должны использовать HttpWebRequest вместо HttpClient.
  2. Если вы хотите получать сообщения о проделанной работе, откройте файл как FileStream и вручную выполните итерацию по нему, скопировав байты в процентах на поток запроса (загрузки). По мере того как вы идете, вы можете рассчитать свой прогресс относительно размера файла.

Код примера TL. Be sure to read the article though!:

long UploadFile(string path, string url, string contentType) 
{ 
    // Build request 
    var request = (HttpWebRequest)WebRequest.Create(url); 
    request.Method = WebRequestMethods.Http.Post; 
    request.AllowWriteStreamBuffering = false; 
    request.ContentType = contentType; 
    string fileName = Path.GetFileName(path); 
    request.Headers["Content-Disposition"] = string.Format("attachment; filename=\"{0}\"", fileName); 

    try 
    { 
     // Open source file 
     using (var fileStream = File.OpenRead(path)) 
     { 
      // Set content length based on source file length 
      request.ContentLength = fileStream.Length; 

      // Get the request stream with the default timeout 
      using (var requestStream = request.GetRequestStreamWithTimeout()) 
      { 
       // Upload the file with no timeout 
       fileStream.CopyTo(requestStream); 
      } 
     } 

     // Get response with the default timeout, and parse the response body 
     using (var response = request.GetResponseWithTimeout()) 
     using (var responseStream = response.GetResponseStream()) 
     using (var reader = new StreamReader(responseStream)) 
     { 
      string json = reader.ReadToEnd(); 
      var j = JObject.Parse(json); 
      return j.Value<long>("Id"); 
     } 
    } 
    catch (WebException ex) 
    { 
     if (ex.Status == WebExceptionStatus.Timeout) 
     { 
      LogError(ex, "Timeout while uploading '{0}'", fileName); 
     } 
     else 
     { 
      LogError(ex, "Error while uploading '{0}'", fileName); 
     } 
     throw; 
    } 
}