2012-06-13 218 views
4

我向WebClient的DownloadProgressChanged事件添加了一個事件處理程序,但它似乎從未觸發。該文件已成功下載,但未更新其進度。WebClient.DownloadProgressChanged永遠不會被調用

public class DownloadFile 
{ 
    private File file = null; 

    public DownloadFile(File file) 
    { 
     this.file = file; 
    } 

    public void startDownloadThread() 
    { 
     Console.WriteLine("Starting Download : "+file.URL); 

     var t = new Thread(() => DownloadThread(file)); 
     t.Start(); 
    } 

    public Action<string> action_error_downloadFailed = Console.WriteLine; 
    private void DownloadThread(File file) //Unnecessary argument but whatever ;D 
    { 
     try 
     { 
      string url = file.URL; 
      string savepath = file.DestinationDir + "\\" + file.Filename; 

      WebClient_B client = new WebClient_B(); 
      client.Proxy = null; //default to no proxy 
      client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); 
      client.DownloadFile(url, savepath); 

      Console.WriteLine("Download finished :" + file.Filename); 
     } 
     catch (Exception ex) 
     { 
      if (action_error_downloadFailed != null) 
       action_error_downloadFailed("Download failed :"+ex.Message); 
     } 
    } 

    private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 
    { 
     try 
     { 
      if (file.TotalSize == 0) 
       file.TotalSize = (int)e.TotalBytesToReceive; 
      file.CurrentSize = (int)e.BytesReceived; 

      Form_DownloadManager.rebuildQueue(); 

      Console.WriteLine("{0} downloaded {1} of {2} bytes. {3} % complete...", 
      (string)e.UserState, 
      e.BytesReceived, 
      e.TotalBytesToReceive, 
      e.ProgressPercentage); 
     } 
     catch (Exception ex) { Console.WriteLine("client_DownloadProgressChanged error : "+ex.Message); } 
    } 
} 

輸出:

Starting Download : http://x.x.x/y/z.zip 
'projectname.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 
The thread '<No Name>' (0x3b8c) has exited with code 0 (0x0). 
Download finished :z.zip 

我使用WebClient_B,因爲我不得不用戶代理+的CookieContainer功能添加到WebClient類,因爲我的服務器一直拒絕下載請求。不過,這個事件從來沒有用'標準'WebClient類別開除。所以這不應該是問題。但不管怎麼說; link to class

回答

8
client.DownloadFile(url, savepath); 

您必須使用異步版本下載文件,目前使用阻塞,同步版本。

msdn docsWebClient.DownloadProgressChanged

異步下載操作成功轉移 部分或全部數據的發生。

在你的情況,這將是:

client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); 
client.DownloadFileAsync (url, savepath); 

因爲你的方法不直接返回任何結果,這個重構不應該是一個問題,不過要注意的是,下載最有可能尚未完成到方法返回給調用者的時候。

+1

詳細'DownloadProgressChanged'和'DownloadFileCompleted'處理程序都執行其稱爲線程'DownloadDataAsync'(根據我的測試)。 –

5

如果你想使用同步Web客戶端,同時獲得最新進展,你可以靠這個方法在這裏

http://alexfeinberg.wordpress.com/2014/09/14/how-to-use-net-webclient-synchronously-and-still-receive-progress-updates/

public void DownloadFile(Uri uri, string desintaion) 
{ 
    using(var wc = new WebClient()) 
    { 
    wc.DownloadProgressChanged += HandleDownloadProgress; 
    wc.DownloadFileCOmpleted += HandleDownloadComplete; 

    var syncObj = new Object(); 
    lock(syncObject) 
    { 
     wc.DownloadFileAsync(sourceUri, destination, syncObject); 
     //This would block the thread until download completes 
     Monitor.Wait(syncObject); 
    } 
    } 

    //Do more stuff after download was complete 
} 

public void HandleDownloadComplete(object sender, AsyncCompletedEventArgs args) 
{ 
    lock(e.UserState) 
    { 
     //releases blocked thread 
     Monitor.Pulse(e.UserState); 
    } 
} 


public void HandleDownloadProgress(object sender, DownloadProgressChangedEventArgs args) 
{ 
    //Process progress updates here 
} 
+0

您是否認爲syncObj是鎖的參數? –

相關問題