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更新和下载)?
答案 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的缓冲区。
要注意的一件事是,不是要连续分配新的字节缓冲区,而是使用缓冲池回收这些固定大小的缓冲区