Descarga de archivos asíncronos con barra de progreso

Estoy intentando que el progreso de la barra de progreso cambie a medida que cambie el progreso de la descarga de WebClient . Este código todavía descarga el archivo cuando llamo startDownload() la ventana se congela mientras descarga el archivo. Me gustaría que el usuario pueda ver el cambio de progreso a medida que se carga la pantalla de bienvenida. ¿Hay alguna manera de solucionar esto para que el usuario pueda ver el progreso del progressBar2 cambiar?

 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"; } 

Debería llamar a startDownload() desde el hilo de UI. La idea de WebClient.DownloadFileAsync() es que engendrará automáticamente un hilo de trabajo sin bloquear el hilo de llamada. En startDownload() , especificó devoluciones de llamada que modifican los controles que supongo fueron creados por el subproceso de la interfaz de usuario. Por lo tanto, si llama a startDownload() desde un hilo de fondo, causará problemas, porque un hilo solo puede modificar los elementos de la IU que creó.

La forma en que se supone que debe funcionar es que startDownload() desde el subproceso de la interfaz de usuario, startDownload() como definió, configura las llamadas de respaldo de eventos que maneja el subproceso de la interfaz de usuario. A continuación, inicia la descarga de forma asincrónica y regresa inmediatamente. El subproceso de interfaz de usuario será notificado cuando el progreso cambie y el código responsable de actualizar el control de barra de progreso se ejecutará en el subproceso de interfaz de usuario, y no debería haber ningún problema.

El subproceso UI se congelará cuando haga clic en startDownload () . Si no desea que se congele el formulario, use startDownload () en otro hilo y realice la actualización del progreso en cross-threaded. De una sola mano,

 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"; }); } 

Lea más sobre multithreading en Google de esta manera http://msdn.microsoft.com/en-us/library/ms951089.aspx

-Firmado faltante cerca); a la statement bgThread

Creo que este artículo lo guiará en la dirección correcta http://www.dreamincode.net/forums/topic/115491-download-file-asynchronously-with-progressbar/ .

Y en este artículo de MSDN, http://msdn.microsoft.com/en-us/library/ms229675.aspx se explica cómo “El archivo se descarga en el subproceso de trabajo del componente BackgroundWorker, que ejecuta el controlador de eventos DoWork. el código llama al método RunWorkerAsync “.

  public class ProgressEventArgsEx { public int Percentage { get; set; } public string Text { get; set; } } public async static Task DownloadStraingAsyncronous(string url, IProgress progress) { WebClient c = new WebClient(); byte[] buffer = new byte[1024]; var bytes = 0; var all = String.Empty; using (var stream = await c.OpenReadTaskAsync(url)) { int total = -1; Int32.TryParse(c.ResponseHeaders[HttpRequestHeader.ContentLength], out total); for (; ; ) { int len = await stream.ReadAsync(buffer, 0, buffer.Length); if (len == 0) break; string text = c.Encoding.GetString(buffer, 0, len); bytes += len; all += text; if (progress != null) { var args = new ProgressEventArgsEx(); args.Percentage = (total <= 0 ? 0 : (100 * bytes) / total); progress.Report(args); } } } return all; } // Sample private async void Bttn_Click(object sender, RoutedEventArgs e) { //construct Progress, passing ReportProgress as the Action var progressIndicator = new Progress(ReportProgress); await TaskLoader.DownloadStraingAsyncronous(tbx.Text, progressIndicator); } private void ReportProgress(ProgressEventArgsEx args) { this.statusText.Text = args.Text + " " + args.Percentage; }