You close the loop variable in the second case - try the following:
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"); }); }
Also Parallel.ForEach() is synchronous - after its execution all files have been downloaded. Tasks, on the other hand, can still go on, so you have to wait for them to complete, perhaps something like this would be more suitable for the second case:
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);
As you can see, Parallel.ForEach() is very preferable in this case, since the syntax is very short, they both use a thread pool under the hood, so choose the simplest option that you can get rid of, especially since you do not need additional complexity.
Also, I donβt think that you get your data faster with WebRequest - most of the delay will be caused by the network / Internet, and not from the two that you choose - that if I were to choose a simpler code, which definitely uses WebClient .
To summarize: I would go for Parallel.ForEach() with WebClient , option 1 .
source share