永远不会在HttpWebResponse中结束Stream

时间:2011-03-05 17:36:05

标签: c# .net httpwebresponse

我怎样才能读取一些字节并断开连接?我使用这样的代码

using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
    using (Stream sm = resp.GetResponseStream())
    {
        using (StreamReader sr = new StreamReader(sm, Encoding.Default))
        {
            sr.Read();
            sr.Close();
        }
    }
}

但它等待流的结束

5 个答案:

答案 0 :(得分:5)

除非您确定该流包含换行符,否则您可能不希望使用StreamReader来读取WebResonse流。 StreamReader喜欢用行来思考,如果流中没有任何换行符,它就会挂起。

最好的办法是在byte[]缓冲区中读取所需的字节数,然后将其转换为文本。例如:

int BYTES_TO_READ = 1000;
var buffer = new byte[BYTES_TO_READ];

using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
    using (Stream sm = resp.GetResponseStream())
    {
        int totalBytesRead = 0;
        int bytesRead;
        do
        {
            // You have to do this in a loop because there's no guarantee that
            // all the bytes you need will be ready when you call.
            bytesRead = sm.Read(buffer, totalBytesRead, BYTES_TO_READ-totalBytesRead);
            totalBytesRead += bytesRead;
        } while (totalBytesRead < BYTES_TO_READ);

        // Sometimes WebResponse will hang if you try to close before
        // you've read the entire stream.  So you can abort the request.
        request.Abort();
    }
}

此时,缓冲区具有缓冲区中的第一个BYTES_TO_READ字节。然后,您可以将其转换为字符串,如下所示:

string s = Encoding.Default.GetString(buffer);

如果您想使用MemoryStream,也可以在缓冲区上打开StreamReader

如果你没有阅读所有内容,我有时会遇到WebResponse。我不知道它为什么这样做,我无法可靠地重现它,但我发现如果我在关闭流之前做request.Abort(),一切正常。见

另一方面,你想要的词是“反应迟钝的”,而不是“不负责任的”。

答案 1 :(得分:4)

你可以这样做吗?

        string GetWebPageContent(string url)
        {
            string result = string.Empty;
            HttpWebRequest request;
            const int bytesToGet = 1000;
            request = WebRequest.Create(url) as HttpWebRequest;

//get first 1000 bytes
            request.AddRange(0, bytesToGet - 1);

            using (WebResponse response = request.GetResponse())
            {
                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                {
                    result = sr.ReadToEnd();
                }
            }
            return result;
        }

关键是在您的请求中使用AddRange

答案 2 :(得分:1)

这是因为http 1.1连接是持久连接默认且tcp连接尚未关闭,所以流不接收结束。

你可以使用myHttpWebRequest1.KeepAlive = false; 所以在http响应之后tcp连接将关闭。

https://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.connection(v=vs.110).aspx#

答案 3 :(得分:0)

如果您正在谈论winforms或webforms,我会将请求放入线程池(如果您使用.net 4,则为任务)。 Streams,即使处理得很好,也很容易将GUI置于大多数用户不喜欢的等待状态。

答案 4 :(得分:0)

我有类似的永不停止的请求解析与此处列出的示例。以下是我提出的消除这些问题的方法:

// url is a string where the request is going.
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;

// Do what you have to do with the Request.

StringBuilder builder = new StringBuilder();
int toRead = 1000;

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    HttpStatusCode status = response.StatusCode;

    using (Stream receiveStream = response.GetResponseStream())
    {
        using (StreamReader readStream = new StreamReader(receiveStream, Encoding.GetEncoding("utf-8")))
        {
            Char[] read = new Char[toRead];
            int count = readStream.Read(read, 0, toRead);

            while (count > 0)
            {
                string str = new String(read, 0, count);
                builder.Append(str);

                count = readStream.Read(read, 0, toRead);
            }

            readStream.Close();
        }   
    }

    response.Close();
}

return builder.ToString();