Запись потока HttpWebRequest никогда не завершается - PullRequest
0 голосов
/ 03 июня 2011

Я публикую файл с HttpWebRequest вместе с верхним и нижним колонтитулом.Заголовок (около 0,5 КБ) и сам файл выглядят нормально, но при больших файлах (около 15 МБ) нижний колонтитул (размером около 29 байт) никогда не записывается.

using (Stream requestStream = request.GetRequestStream()) {
    requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

    byte[] buffer = new byte[Math.Min(4096L, fileSize)];
    int bytesRead = 0;
    while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) {
        requestStream.Write(buffer, 0, bytesRead);
    }

    // next line never completes                        
    requestStream.Write(postFooterBytes, 0, postFooterBytes.Length);

    // code below is never reached
    Console.WriteLine("Why do I never see this message in the console?");
}

Есть какие-нибудь мысли?

ETA: Попытка промывки потока перед последним Write(), на случай, если это поможет, но безрезультатно.

Отредактировано снова: Добавлен using(), чтобы уточнить, что я не полный идиот.Также обратите внимание, что он находится внутри другого using() блока для fileStream.

Ответы [ 3 ]

2 голосов
/ 03 июня 2011

Решено: Выключено AllowWriteStreamBuffering на HttpWebRequest.Похоже, когда он включен, какой бы вызов Write() не записал последний байт, он не вернется, пока внутренний буфер не очистится.Таким образом, последний Write() в конечном итоге соревновался, но только после того, как у меня кончилось терпение.

И поскольку первоначально я пытался определить прогресс, отключение буферизации все равно проясняет ситуацию.

1 голос
/ 03 июня 2011

Распространенная проблема - забыть закрыть поток запросов. Один из симптомов, который вы увидите, заключается в том, что запрос никогда не делается. Вполне вероятно, что запись действительно завершается, но, поскольку вы не закрыли поток запросов, вызов HttpWebRequest.GetResponse() не выполняется.

Попробуйте следующее и посмотрите, имеет ли это значение:

using (var requestStream = myRequest.GetRequestStream())
{
    // write to the request stream here
}
// Now try to get the response.

Другая возможная проблема - размер данных. Во-первых, вы уверены, что сервер может обрабатывать загрузку 15 МБ? Во-вторых, если вы делаете это при медленном соединении, отправка 15 МБ может занять некоторое время. У меня есть то, что считается «быстрым» восходящим соединением со скоростью 1,5 Мбит / с. Это в лучшем случае 0,15 мегабайта в секунду. Отправка 15 мегабайт займет полторы минуты.

Еще одна возможность - время ожидания запроса. Вы хотите просмотреть свойства HttpWebRequest.Timeout и ReadWriteTimeout.

0 голосов
/ 03 июня 2011

Когда вы создаете свой запрос, длина вашего контента также должна включать заголовки, убедитесь, что она не просто установлена ​​на длину файла.Другая вещь, которую вы можете попробовать, это вызвать .Flush() в потоке, когда все сказано и сделано.Я не уверен в том, что закрытие потока для HttpClient, как предполагает Джим, может сработать, может ухудшить ситуацию.

Разве использование System.Net.WebClient не обеспечивает достаточной гибкости для вас?Theres хороший UploadFile() метод, который вы можете использовать.

...