关于在HttpWebRequest GetResponseStream中选择缓冲区大小

时间:2015-05-02 09:00:07

标签: c# httpwebrequest size buffer

var h = (HttpWebRequest)WebRequest.Create(url);
using (var hr = (HttpWebResponse)(await h.GetResponseAsync()))
{
    using (var s = hr.GetResponseStream())
    {
        using (var f = new FileStream(saveTo, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            int bytesCount = 0;
            byte[] buf = new byte[2048]; //<------------------------------

            while ((bytesCount = await s.ReadAsync(buf, 0, buf.Length)) > 0)
            {
                await f.WriteAsync(buf, 0, bytesSize);
                // Update UI : downloaded size, percent,...
            }
        }
    }
}

我正在编写下载程序支持更新UI (ObservableCollection of thounsands items - Batch download),当下载进度发生变化并恢复下载但支持多段时下载(因为每个项目的大小通常&lt; 10MB) 我运行大约5-20次下载并发。什么缓冲区大小适合这种情况(适用于UI更新和下载)?

1 个答案:

答案 0 :(得分:3)

您希望使用的缓​​冲区大小是操作系统页面大小的倍数,因为这是写入磁盘和内存中页面的粒度。使用小于OS页面大小的任何内容都不是最理想的。

OS页面通常为4096字节。 FileStream的默认缓冲区大小,如果在构造期间没有提供缓冲区大小时使用,也是4096字节。

对于磁盘I / O,通常最好使用稍大的缓冲区(32-128 KB)。

在您的方案中,使用最多20个并发下载,如果您使用32或64 KB的缓冲区大小,这将只需要640 KB或1.2 MB的内存,因此这些显然是可行的选项。

假设您在美国,宽带和移动设备的平均下载速度分别为23 Mbps和12 Mbps,那么如果您使用64 KB缓冲区(120 MB并发下载1.2 MB),则可以更新UI每秒20次下载中的每一次。

因此,使用至少32 - 64 KB的缓冲区。

要注意的一件事是,不是要连续分配新的字节缓冲区,而是使用缓冲池回收这些固定大小的缓冲区