【问题标题】:WebClient.DownloadFile() within Parallel.ForEachParallel.ForEach 中的 WebClient.DownloadFile()
【发布时间】:2011-03-29 00:43:44
【问题描述】:

这段代码运行良好:

Parallel.ForEach(photos, item =>
            {
                WebClient webClient = new WebClient();
                webClient.DownloadFile(item.src_big, "C:\\pic" + item.ID + ".jpg");
            });

虽然此代码抛出“WebClient 请求期间发生异常”。 :

foreach (Photo p in photos)
        {
            Task.Factory.StartNew(() =>
                {
                    WebClient webClient = new WebClient();
                    webClient.DownloadFile(p.src_big, "C:\\pic" + p.ID + ".jpg");
                });
        }

我有两个问题:

1) 在第一个代码中,我使用多个 WebClient 对象进行下载。第二个代码也是如此,为什么会出现异常?

2)我正在尝试这两个版本来确定下载照片的最快方式是什么,在我的例子中是从 facebook 下载的。我想知道是否有另一种更快的方法,也许是 WebRequest.Create() ?

【问题讨论】:

  • 对 2 的回答是我正在使用相同的程序,并且它对我并行工作正常。foreach 大大减少了时间

标签: c# webclient parallel-processing


【解决方案1】:

在第二种情况下你是closing over the loop variable - 试试这个:

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

【讨论】:

  • 酷,工作!那么我的第二个问题呢,你有什么见解吗?
  • 好的,但是 webclient.DownloadData() 呢?如果它更快,也许我可以使用它,并在另一个线程中转换为 jpg?
  • 我认为你想多了 - 但我鼓励你使用这两种方法进行一些性能测试 - 我认为任何一种都不会比另一种快得多 - 所以让它变得简单因为你可以逃脱。
  • 我用 Network Meter 小工具检查了下载速率,确实我的下载速率是 700kb,这是我的最大值。所以解决方案 1 是最快的。
【解决方案2】:

Asnwer 到 2 是我正在使用相同的程序,它对我来说工作正常,parallel.foreach 大大减少了时间

当我分析静态数据时,我观察到如果我有大量图片要获取,那么 parallel.foreach 会启动如此多的线程,以至于它几乎达到了我的宽带的 cpapcity,就像我的最大常规下载速度为 100kb/sec所以下载图片达到了 100kb 这意味着它没有比这更好的了,因为它是最重要的互联网

【讨论】:

  • 好点!我会检查下载速度。顺便问一下,你如何检查它? (-:(我的意思是最准确的方法)
  • 简单的是我的 LAN 以 100 Mbps 的速度连接,当我运行这个进程时,我可以通过任务管理器看到它的消耗,它是 1%,这意味着 1Mbps
猜你喜欢
  • 2017-12-16
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
相关资源
最近更新 更多