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