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 ()
?
Спасибо за ваши просветления.
Ответы
Ответ 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 является преждевременной оптимизацией, если вам не требуется значительная прибыль.