限制HttpWebResponse流的读取速度

时间:2013-03-16 12:16:33

标签: .net multithreading asynchronous

我使用此代码来读取HttpWebResponse流

                Stream stm = httpResp.GetResponseStream();
                Stream fs = new FileStream(filename, FileMode.Append, FileAccess.Write);
                byte[] buff = new byte[1024 * 16];

                AsyncCallback callback = null;
                callback = ar =>
                {
                    int bytesRead = stm.EndRead(ar);
                    fs.Write(buff, 0, bytesRead);
                    if(bytesRead == 0)
                        return;

                    stm.BeginRead(buff, 0, buff.Length, callback, null);
                };
                stm.BeginRead(buff, 0, buff.Length, callback, null);

我想限制下载速度。如果我在回调中放置一个Thread.Sleep(),它将阻止线程,但它不会很好地扩展到许多流。 有没有其他方法可以实现下载限制和线程经济?

1 个答案:

答案 0 :(得分:0)

在循环中进行睡眠可能会限制下载速率。它取决于底层协议实现和内部网络流缓冲区的大小。

在我的系统(Windows Server 2008,.NET 4.5)上,将睡眠置入循环会限制下载速度。

它还取决于request.AllowReadStreamBuffering属性的设置。文档说默认设置为true,但我的测试显示系统上的默认值为false。事实上,尝试将其设置为true会引发异常。

但是,似乎Silverlight的默认值为true。有关该属性,请参阅the Silverlight doc。设置为true时,将在响应准备好读取之前读取并缓冲整个响应。

假设限制读取请求的速率将限制下载速率(这似乎是合理的,只要您禁用读取流缓冲),我认为没有一种好方法可以使用BeginRead / {{1 }}。正如你所指出的那样,将EndRead置于其中并不能很好地扩展。

使用.NET 4.5和C#5.0,您应该考虑使用Thread.Sleep来获取响应,并在阅读响应流时使用GetResponseAsync。使用.NET 4.0,您可以创建Task来进行阅读。这些都可以让您使用Task.Delay来创建延迟。这与控制下载速度的ReadAsync具有相同的效果,但不会阻止该线程。

不幸的是,我没有你的例子。