HttpWebRequest.GetRequestStream:它做什么?

时间:2011-03-16 13:13:40

标签: c# httpwebrequest

代码示例:

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 ()到底是做什么的吗?

感谢您的启发。

2 个答案:

答案 0 :(得分:22)

获取请求流不会触发帖子,但关闭流会发生。发布数据按以下方式发送到服务器:

  1. 与主持人建立连接
  2. 发送请求和标题
  3. 撰写发布数据
  4. 等待回应。
  5. 刷新和关闭流的行为是最后一步,一旦输入流关闭(即客户端已将所需内容发送到服务器),服务器就可以返回响应。

答案 1 :(得分:9)

使用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将引发超时异常的情况中恢复。

一般来说,线程很便宜。如果您有10,000个或更多并发请求,则HttpWebRequest的异步Begin / End方法仅值得使用;因为实现超时非常棘手且容易出错。通常,使用BeginGetRequestStream是过早优化,除非您需要显着的性能提升。