2016-12-28 55 views
-1

我想要的是開始下載第一個圖像保存到硬盤。 一旦下載完成並且progressBar達到100%,就開始下載下一張圖像。等等。如何使用WebClient下載許多圖像異步?

我嘗試這樣做:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.IO; 
using System.Net; 

namespace SatelliteImages 
{ 
    public partial class Form1 : Form 
    { 
     int count = 0; 

     public Form1() 
     { 
      InitializeComponent(); 

      ExtractImages ei = new ExtractImages(); 
      ei.Init(); 

      startDownload(); 
     } 

     private void startDownload() 
     { 
      WebClient client = new WebClient(); 
      client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); 
      client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); 
      foreach (string url in ExtractImages.imagesUrls) 
      { 
       client.DownloadFileAsync(new Uri(url), @"C:\Temp\TestingSatelliteImagesDownload\" + count + ".jpg"); 
      } 
     } 

     void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 
     { 
      double bytesIn = double.Parse(e.BytesReceived.ToString()); 
      double totalBytes = double.Parse(e.TotalBytesToReceive.ToString()); 
      double percentage = bytesIn/totalBytes * 100; 
      label1.Text = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive; 
      progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); 
     } 
     void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
     { 
      label1.Text = "Completed"; 
      count++; 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 

     } 
    } 
} 

列表imagesUrls包含這樣的格式,例如鏈接中的第一項:

http://www.sat24.com/image2.ashx?region=eu&time=201612281630&ir=true

如果我將瀏覽到此鏈接在Chrome將是精細。 但是當我試圖下載的圖像並保存在硬盤我上線得到例外的圖像:

client.DownloadFileAsync(new Uri(url), @"C:\Temp\TestingSatelliteImagesDownload\" + count + ".jpg"); 

其他信息:Web客戶端不支持併發I/O操作。

System.NotSupportedException was unhandled 
    HResult=-2146233067 
    Message=WebClient does not support concurrent I/O operations. 
    Source=System 
    StackTrace: 
     at System.Net.WebClient.ClearWebClientState() 
     at System.Net.WebClient.DownloadFileAsync(Uri address, String fileName, Object userToken) 
     at System.Net.WebClient.DownloadFileAsync(Uri address, String fileName) 
     at SatelliteImages.Form1.startDownload() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Form1.cs:line 37 
     at SatelliteImages.Form1..ctor() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Form1.cs:line 27 
     at SatelliteImages.Program.Main() in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\Program.cs:line 19 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 
+1

http://stackoverflow.com/questions/25371743/await-multiple-file-downloads-with-downloaddataasync#25371913 – RamblinRose

+1

在這裏看到:http://stackoverflow.com/questions/9765109/webclient-does -not-support-concurrent-io-operations - webclient不允許同時發出多個請求。您必須將其作爲異步方法進行包裝,以同步方式調用Web客戶端並返回圖像。 –

+3

你看過使用'HttpClient'而不是'WebClient'嗎? –

回答

1

您只能使用webclient實例,直到不忙,因爲它不支持併發呼叫。所以之後每次下載endend這樣您就必須使用新的WebClient實例每次下載或鏈中的呼叫:

//On initialize form : 
     WebClient client = new WebClient(); 

    //On start download : 

     client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); 
     client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); 
     client.DownloadFileAsync(new Uri(url), @"C:\Temp\TestingSatelliteImagesDownload\" + ExtractImages.imagesUrls[currentImageIndex] + ".jpg"); 
... 
     void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
     { 
if(currentImageIndex<ImageToDownloadCount){ 
currentImageIndex +=1; 
     client.DownloadFileAsync(new Uri(url), @"C:\Temp\TestingSatelliteImagesDownload\" + ExtractImages.imagesUrls[currentImageIndex] + ".jpg"); 
} 

      label1.Text = "Completed"; 
      count++; 
     } 

希望它能幫助。

1

使用DownloadFileTaskAsync用於異步下載。

public event EventHandler TaskCompleted; 

    public async void DownloadAsync() 
    { 
     String[] urls = { "http://media.salon.com/2014/10/shutterstock_154257524-1280x960.jpg", 
          "http://www.samsung.com/us/2012-smart-blu-ray-player/img/tv-front.png" }; 
     var tasks = urls.Select((url, index) => 
     { 
      var fileName = String.Format(@"c:\temp\image-{0}.jpg", index); 
      var client = new WebClient(); 
      return client.DownloadFileTaskAsync(url, fileName); 
     }); 
     await Task.WhenAll(tasks).ContinueWith(x => 
     { 
      if (TaskCompleted != null) 
      { 
       TaskCompleted(this, EventArgs.Empty); 
      } 
     }); 
    }