【问题标题】:Possible Infinite Loop when streaming response流式响应时可能出现无限循环
【发布时间】:2013-04-30 15:37:50
【问题描述】:

我们正在尝试确定我们拥有的服务中的高 CPU 使用率,并且我们认为有一些潜在的区域可能会导致无限循环。下面是我们认为可能导致无限循环的代码。有没有什么特别突出的东西可能导致 while 循环无限期地运行?

            WebRequest request = WebRequest.Create(Url);
            request.ContentLength = formDataLength;
            request.ContentType = "application/x-www-form-urlencoded";
            request.Method = "POST";

            using (Stream rs = request.GetRequestStream())
            {
                ASCIIEncoding encoding = new ASCIIEncoding();
                var postData = encoding.GetBytes(formData);
                rs.Write(postData, 0, postData.Length);

                string str = string.Empty;
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    using (Stream sm = response.GetResponseStream())
                    {
                        int totalBytesRead = 0;
                        long responseBytesToRead = 1024;
                        byte[] buffer = new byte[responseBytesToRead];
                        int bytesRead;
                        do
                        {
                            bytesRead = sm.Read(buffer, totalBytesRead, (int)(responseBytesToRead - totalBytesRead));
                            totalBytesRead += bytesRead;
                        } while (totalBytesRead < bytesRead);

                        request.Abort();
                        str = Encoding.Default.GetString(buffer);
                    }
                }
                return str;
           }

【问题讨论】:

  • 有什么理由不使用WebClient class?使用它会将您的代码缩短到 4-5 行。

标签: c# io stream infinite-loop


【解决方案1】:

来自MSDN 文档:

返回值
类型:System.Int32 读入的总字节数 缓冲区。这可能小于请求的字节数,如果 那么多字节当前不可用,如果结束则为零 (0) 已到达流。

0 表示流的结束。已经定义了到达流末端的条件。您所依赖的条件可能不可靠且没有必要。

试试

while(bytesRead != 0)

【讨论】:

  • 我同意这种情况......很奇怪,但它不应该导致无限循环。 bytesRead 最终仍应小于或等于 totalBytesRead。我认为其他原因导致了延迟。
  • @Cemafor - 我同意,这很难说。我肯定会通过单元测试运行这段代码。
【解决方案2】:

最好用StreamReader

 using (StreamReader reader = new StreamReader(response.GetResponseStream()))
...
 reader.ReadToEnd();

// or

 while (!reader.EndOfStream)
 {
    // do read.
 }

【讨论】:

    猜你喜欢
    • 2021-04-21
    • 1970-01-01
    • 2013-04-26
    • 2012-02-23
    • 2021-09-05
    • 2019-10-13
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多