2012-02-27 23 views
14

Sto tentando di modificare la progressione della barra di avanzamento mentre le modifiche allo stato di avanzamento del download dello WebClient. Questo codice ancora scarica il file ancora quando chiamo startDownload() la finestra si blocca mentre scarica il file. Vorrei che l'utente fosse in grado di vedere i cambiamenti di avanzamento mentre si caricava la schermata iniziale. C'è un modo per risolvere questo problema in modo che l'utente possa vedere il progresso della modifica progressBar2?Download file asincrono con barra di avanzamento

private void startDownload() 
{ 
    WebClient client = new WebClient(); 
    client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); 
    client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); 
    client.DownloadFileAsync(new Uri("http://joshua-ferrara.com/luahelper/lua.syn"), @"C:\LUAHelper\Syntax Files\lua.syn"); 
} 
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; 
    label2.Text = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive; 
    progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); 
} 
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    label2.Text = "Completed"; 
} 
+0

se la finestra si blocca significa che la persona sta scaricando sul thread dell'interfaccia utente che si traduce in un codice sincrono e non asincrono. – Joakim

+0

Sto chiamando 'startDownload()' attraverso un background worker in esecuzione in modo asincrono. Ciò non dovrebbe però bloccare la finestra, giusto? –

+6

Si prega di non anteporre i titoli con "C#" e così via. Ecco a cosa servono i tag. –

risposta

9

È necessario chiamare startDownload() dal thread dell'interfaccia utente. L'idea di WebClient.DownloadFileAsync() consiste nel generare automaticamente un thread di lavoro automaticamente senza bloccare il thread chiamante. In startDownload(), hai specificato i callback che modificano i controlli che presumo siano stati creati dal thread dell'interfaccia utente. Pertanto, se si chiama startDownload() da un thread in background, si verificheranno dei problemi, poiché un thread può solo modificare gli elementi dell'interfaccia utente creati.

Il modo in cui deve funzionare è che si chiama startDownload() dal thread dell'interfaccia utente, startDownload() come definito imposta le richiamate di eventi gestite dal thread dell'interfaccia utente. Quindi avvia il download in modo asincrono e restituisce immediatamente. Il thread dell'interfaccia utente verrà notificato quando il progresso cambia e il codice responsabile dell'aggiornamento del controllo della barra di avanzamento verrà eseguito sul thread dell'interfaccia utente e non dovrebbero esserci problemi.

+0

Grazie, non mi ero reso conto che non sarei stato in grado di avviare il download tramite un altro thread asincrono. Tutto sta funzionando bene ora. –

1

Credo che questo articolo ti guidi nella giusta direzione http://www.dreamincode.net/forums/topic/115491-download-file-asynchronously-with-progressbar/.

E in questo MSDN l'articolo http://msdn.microsoft.com/en-us/library/ms229675.aspx illustra come "Il file viene scaricato sul thread di lavoro del componente BackgroundWorker, che esegue il gestore di eventi DoWork. Questo thread si avvia quando il codice chiama il metodo RunWorkerAsync."

+0

Ho già seguito quell'articolo che ha portato allo stesso problema. –

+2

Stai utilizzando la funzione per mostrare il progresso del download dal thread in background? In tal caso, dovresti avviarlo nel thread dell'interfaccia utente, ma agganciare la funzione di avanzamento del worker in background. Spero che possa essere di qualche aiuto. Sto ancora leggendo i problemi che stai avendo, quindi spero di riuscire a trovare un'altra soluzione. – SMT

18

UI Il thread verrà congelato quando si fa clic su startDownload(). Se non si desidera ottenere il congelamento del modulo, utilizzare startDownload() in un altro thread e procedere all'aggiornamento nel thread incrociato. Un modo,

private void startDownload() 
{ 
    Thread thread = new Thread(() => { 
      WebClient client = new WebClient(); 
      client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); 
      client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); 
      client.DownloadFileAsync(new Uri("http://joshua-ferrara.com/luahelper/lua.syn"), @"C:\LUAHelper\Syntax Files\lua.syn"); 
    }); 
    thread.Start(); 
} 
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 
{ 
    this.BeginInvoke((MethodInvoker) delegate { 
     double bytesIn = double.Parse(e.BytesReceived.ToString()); 
     double totalBytes = double.Parse(e.TotalBytesToReceive.ToString()); 
     double percentage = bytesIn/totalBytes * 100; 
     label2.Text = "Downloaded " + e.BytesReceived + " of " + e.TotalBytesToReceive; 
     progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); 
    }); 
} 
void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    this.BeginInvoke((MethodInvoker) delegate { 
     label2.Text = "Completed"; 
    }); 
} 

Leggi tutto multi-threading in Google come questo http://msdn.microsoft.com/en-us/library/ms951089.aspx

-Corretto mancante vicino); alla dichiarazione bgThread

+0

MethodInvoker non viene nel mio programma cosa devo fare –

+1

BeginInvoke si trova nello spazio dei nomi di WinForms. Se stai usando WPF dovresti usare Dispatcher.BeginInvoke – Tsukasa

+0

Usare il codice sopra per scaricare i file ma, non riesco a connettere l'errore del server remoto. –

Problemi correlati