c# - Parallel.ForEach 中的 WebClient.DownloadFile()

标签 c# webclient parallel-processing

这段代码工作正常:

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() ?

最佳答案

你是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

关于c# - Parallel.ForEach 中的 WebClient.DownloadFile(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5466680/

相关文章:

c# - 长时间运行后连接意外关闭 C#

c++ - 如何找到两条平行线段之间的垂直距离?

multithreading - 有哪些不同类型的并行性?

javascript - HTML5 Web Worker 是线程还是进程?

c# - 如何在 C# 中使用 System.Net.WebClient 上传 GZip 压缩数据

c# - 使用参数化查询发送空值

c# - 哈希速度 - 神秘的结果(哈希两次比哈希一次慢得多)

c# - WPF MVVM : Call method from control from inside attached usercontrol

c# - 进度条和网络客户端

C# 6.0 - 意外字符 '$'