HttpWebRequest.GetRequestStream: Что это делает? - PullRequest
33 голосов
/ 16 марта 2011

Пример кода:

HttpWebRequest request =
   (HttpWebRequest)HttpWebRequest.Create("http://some.existing.url");

request.Method = "POST";
request.ContentType = "text/xml";

Byte[] documentBytes = GetDocumentBytes ();


using (Stream requestStream = request.GetRequestStream())
{
   requestStream.Write(documentBytes, 0, documentBytes.Length);
   requestStream.Flush();
   requestStream.Close();
}

Когда я делаю request.GetRequestStream (), в запросе нечего отправлять. Из названия метода и значения intellisense, которое он показывает («Получить System.IO.Stream для использования при записи данных запроса»), ничто не указывает на то, что эта строка кода подключится к удаленному серверу. Но, похоже, это так ...

Может кто-нибудь объяснить мне, что именно делает HttpWebRequest.GetRequestStream ()?

Спасибо за ваши просветления.

Ответы [ 2 ]

22 голосов
/ 16 марта 2011

Получение потока запросов не вызывает публикацию, но закрытие потока делает.Почтовые данные отправляются на сервер следующим образом:

  1. Соединение открывается с хостом
  2. Отправка запроса и заголовков
  3. Запись данных почты
  4. Ожидание ответа.

Процесс очистки и закрытия потока является последним этапом, и как только входной поток закрывается (то есть клиент отправил то, что ему нужно, на сервер), то сервер может вернуть ответ.

9 голосов
/ 16 марта 2011

Вы используете GetRequestStream (), чтобы синхронно получить ссылку на поток загрузки. Фактический запрос отправляется только после того, как вы закончили запись в поток.

Однако я бы предложил использовать метод BeginGetRequestStream вместо GetRequestStream. BeginGetRequestStream работает асинхронно и не блокирует текущий поток во время получения потока. Вы передаете обратный вызов и контекст в BeginGetRequestStream. В обратном вызове вы можете вызвать EndGetRequestStream (), чтобы наконец получить ссылку и повторить шаги написания, перечисленные выше (для синхронного поведения). Пример:

context.Request.BeginGetRequestStream(new AsyncCallback(Foo), context);

public void Foo(IAsyncResult asyncResult)
    {
        Context context = (Context)asyncResult.AsyncState;
        try
        {
            HttpWebRequest request = context.Request;

            using (var requestStream = request.EndGetRequestStream(asyncResult))
            using (var writer = new StreamWriter(requestStream))
            {
                // write to the request stream
            }

            request.BeginGetResponse(new AsyncCallback(ProcessResponse), context);
        }

Будьте очень осторожны с BeginGetRequestStream. Это никогда не истекает, поэтому вы должны добавить дополнительную логику в вашу программу для восстановления в ситуациях, когда GetRequestStream будет выдавать исключение тайм-аута.

В общем, темы дешевые. Методы async Begin / End HttpWebRequest стоит использовать только в том случае, если у вас будет 10 000 или более одновременных запросов; потому что реализация таймаутов очень сложна и подвержена ошибкам. В общем, использование BeginGetRequestStream является преждевременной оптимизацией, если вам не требуется значительный прирост производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...