我希望从网站下载大约 100,000 个文件。这个问题的答案与我尝试的问题相同。
我尝试了两种方法,这两种方法都使用非常不稳定的带宽:
第一次尝试同步下载文件:
ParallelOptions a = new ParallelOptions();
a.MaxDegreeOfParallelism = 30;
ServicePointManager.DefaultConnectionLimit = 10000;
Parallel.For(start, end, a, i =>
{
using (var client = new WebClient())
{
...
}
});
这可行,但我的吞吐量如下所示:
第二种方法涉及使用信号量和异步来更手动地进行并行处理(如果没有信号量,它显然会产生太多的工作项):
Parallel.For(start, end, a, i =>
{
list.Add(getAndPreprocess(/*get URL from somewhere*/);
});
...
static async Task getAndPreprocess(string url)
{
var client = new HttpClient();
sem.WaitOne();
string content = "";
try
{
var data = client.GetStringAsync(url);
content = await data;
}
catch (Exception ex) { Console.WriteLine(ex.InnerException.Message); sem.Release(); return; }
sem.Release();
try
{
//try to use results from content
}
catch { return; }
}
我的吞吐量现在看起来像这样:
有没有一种很好的方法可以做到这一点,例如当速度下降时它开始下载另一个文件,并在总速度恒定时停止添加(就像你期望下载管理器做的那样)?
此外,即使第二种形式提供了更好的结果,我也不喜欢必须使用信号量,因为它容易出错。
这样做的标准方法是什么?
注意:这些都是小文件(<50KB)