Подтвердить что ты не робот

HttpWebRequest.GetRequestStream: что он делает?

Пример кода:

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 он показывает ( "Get System.IO.Stream использовать для записи данных запроса" ), ничто не указывает, что эта строка кода будет подключаться к удаленному серверу.
Но, похоже, это так...

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

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

4b9b3361

Ответ 1

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

  • Соединение открывается на хост
  • Отправить запрос и заголовки
  • Запись данных сообщения
  • Подождите ответа.

Акт промывки и закрытия потока - последний шаг, и как только поток ввода закрыт (т.е. клиент отправил то, что ему нужно для сервера), сервер может вернуть ответ.

Ответ 2

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

Однако я бы предположил, что вместо метода GetRequestStream вы используете метод BeginGetRequestStream. 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 будет генерировать исключение тайм-аута.

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