2012-06-13 4 views
4

Я добавил обработчик события в событие DownloadProgressChanged WebClient, но он никогда не срабатывает. Файл успешно загружается, но не обновляется.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, потому что я должен был добавить UserAgent + функциональность cookiecontainer к WebClient класса, так как мой сервер продолжал отвергать запрос на загрузку. Однако событие никогда не запускалось со стандартным классом WebClient. Так что это не должно быть проблемой. Но в любом случае; link to class

ответ

8
client.DownloadFile(url, savepath); 

Вы должны использовать версию асинхронной для загрузки файла, в настоящее время используется блокирование, синхронные версии.

С msdn docs для WebClient.DownloadProgressChanged:

Происходит при асинхронного загрузки операция успешно передает некоторые или все данные.

В вашем случае это будет:

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

Поскольку ваш метод непосредственно не возвращает никакого результата, это рефакторинг не должен быть проблемой, обратите внимание, однако, что загрузка, скорее всего, не была завершена к моменту возвращения метода к вызывающему.

+1

'' DownloadProgressChanged' и обработчики DownloadFileCompleted' оба казнены нить, которая под названием 'DownloadDataAsync' (за мое тестирование). –

5

Если вы хотите использовать WebClient синхронно, при получении прогресса обновления вы можете полагаться на этот метод подробно здесь

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 для param для lock? –

Смежные вопросы