C# Parallel.ForEach中的WebClient.DownloadFile()
此代码工作正常:C# Parallel.ForEach中的WebClient.DownloadFile(),c#,webclient,parallel-processing,C#,Webclient,Parallel Processing,此代码工作正常: Parallel.ForEach(photos, item => { WebClient webClient = new WebClient(); webClient.DownloadFile(item.src_big, "C:\\pic" + item.ID + ".jpg"); }); 当此代码引发“WebClient请求期间发生异常”时: 我有两个问题:
Parallel.ForEach(photos, item =>
{
WebClient webClient = new WebClient();
webClient.DownloadFile(item.src_big, "C:\\pic" + item.ID + ".jpg");
});
当此代码引发“WebClient请求期间发生异常”时:
我有两个问题:
1) 在第一段代码中,我使用多个WebClient对象进行下载。第二个代码也是如此,为什么会出现异常
2) 我正在尝试这两个版本,以确定从facebook下载照片的最快方式。我想知道是否有其他更快的方法,可能是WebRequest.Create() 您处于第二种情况-尝试以下方法:
foreach (Photo p in photos)
{
Photo photo = p;
Task.Factory.StartNew(() =>
{
WebClient webClient = new WebClient();
webClient.DownloadFile(photo.src_big, "C:\\pic" + photo.ID + ".jpg");
});
}
另外,Parallel.ForEach()
是同步的-执行后,所有文件都已下载。另一方面,任务可能仍在进行中,因此您必须等待它们完成,可能类似的情况更适合于第二种情况:
var tasks = photos.Select( p => Task.Factory.StartNew(() =>
{
using(WebClient webClient = new WebClient())
webClient.DownloadFile(p.src_big, string.Format(@"C:\pic{0}.jpg",p.ID));
})).ToArray();
Task.WaitAll(tasks);
如您所见,在这种情况下,首选Parallel.ForEach()
,因为语法非常简洁,它们都使用线程池,所以请选择最简单的选项,特别是因为不需要增加复杂性
此外,我不认为使用WebRequest
会更快地获取数据-大部分延迟都是由网络/互联网造成的,而不是由您选择的两者中的哪一个造成的-在这种情况下,我会选择更简单的代码,这肯定是使用WebClient
总而言之:我会选择
Parallel.ForEach()
和WebClient
,选项1和2相比,我使用的是相同的过程,它对我来说并行工作很好。ForEach大大减少了时间
当我分析静态数据时,我观察到,如果我有大量图片要获取,那么parallel.foreach会启动如此多的线程,几乎达到我宽带的cpapcity,就像我的最大常规下载速度为100kb/秒,因此下载图片达到100kb,这意味着它不会比这更好,因为互联网是最重要的吗?与2相比,我使用的是相同的程序,它对我来说也很好。foreach减少了很多时间,很有效!那么我的第二个问题呢,你有什么见解吗?好的,但是webclient.DownloadData()呢?如果快一点,也许我可以用它来代替,在另一个线程中转换成jpg吗?我想你对这个问题考虑得太多了,但我鼓励你使用这两种方法进行一些性能测试——我不认为这两种方法中的任何一种都会明显快于另一种——所以尽可能简单。我用网络仪表小工具和我的下载速率为700kb,这是我的最大下载速率。因此解决方案1是最快的。这一点很好!我会检查下载率。顺便问一下,你怎么检查?(((我的意思是最准确的方法)简单的是,我的局域网以100 Mbps的速度连接,当我运行这个过程时,我可以通过taskmanager看到它的消耗量,它达到1%,这意味着1Mbps
var tasks = photos.Select( p => Task.Factory.StartNew(() =>
{
using(WebClient webClient = new WebClient())
webClient.DownloadFile(p.src_big, string.Format(@"C:\pic{0}.jpg",p.ID));
})).ToArray();
Task.WaitAll(tasks);