2011-03-29 104 views
4

此代碼工作正常:WebClient.DownloadFile()內Parallel.ForEach

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

儘管此代碼拋出「一個Web客戶端請求期間發生異常。」 :

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

+0

更重要的是,我使用相同的程序,並且它對我很好。parallel.foreach減少了很多時間 – 2011-03-29 00:56:33

回答

7

你是在第二種情況下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,選項。

+0

cool,Worked!我的第二個問題呢,你有什麼見解嗎? – 2011-03-29 00:57:55

+0

@Yaron - 添加到我的答案 – BrokenGlass 2011-03-29 01:04:32

+0

好的,但webclient.DownloadData()呢?如果速度更快,也許我可以使用它,並在另一個線程中轉換爲jpg格式? – 2011-03-29 01:09:57

0

Asnwer 2是我使用同樣的程序,它爲我的作品精細parallel.foreach減少時間多

當我分析了靜的話,我認爲,如果我有大量的圖片來獲取,然後parallel.foreach啓動了這麼多的線程,它幾乎到達我寬帶的寬度,就像我有100kb/sec的最大常規下載速度,所以下載圖片達到100kb,這意味着它不能比這更好,因爲它是互聯網最重要的是

+0

好點!我會檢查下載速度。順便說一下,你如何檢查它?( - :(我的意思是最準確的方式) – 2011-03-29 01:14:05

+0

簡單的是,我的局域網連接速度爲100 Mbps,當我運行這個過程時,我可以通過taskmanager看到它的消耗量,它會達到1%,這意味着1Mbps – 2011-03-29 03:06:46