whenall method ejemplos await asynctask async c# asynchronous webclient

c# - method - ¿Cómo puedo descargar varios archivos usando Asclnc, pero de a uno por vez?



task method c# (3)

Crearía un nuevo método, por ejemplo llamado getUrlFromQueue que me devuelve una nueva url de la cola (colección o matriz) y la elimina ... luego llama a downloadFile (url) - y en client_DownloadFileCompleted llamo getUrlFromQueue nuevamente.

Sorprendentemente, ha sido difícil encontrar un ejemplo de código para descargar varios archivos utilizando el método asíncrono de la clase webcliente, pero descargándolos de uno en uno.

¿Cómo puedo iniciar una descarga asíncrona, pero esperar hasta que la primera termine hasta la segunda, etc. Básicamente una que.

(Tenga en cuenta que no quiero utilizar el método de sincronización, debido a la mayor funcionalidad del método async).

El código a continuación comienza todas mis descargas a la vez. (la barra de progreso está por todos lados)

private void downloadFile(string url) { WebClient client = new WebClient(); client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged); client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted); // Starts the download btnGetDownload.Text = "Downloading..."; btnGetDownload.Enabled = false; progressBar1.Visible = true; lblFileName.Text = url; lblFileName.Visible = true; string FileName = url.Substring(url.LastIndexOf("/") + 1, (url.Length - url.LastIndexOf("/") - 1)); client.DownloadFileAsync(new Uri(url), "C://Test4//" + FileName); } void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { } 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; progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); }


Estoy luchando por entender dónde está el problema. Si solo llama al método asíncrono para el primer archivo, ¿no solo descargará ese archivo? ¿Por qué no utilizar el evento client_downlaodFileCompleted para iniciar la próxima descarga de archivos en función de algún valor aprobado por AsyncCompletedEvents, o mantener una lista de archivos descargados como una variable estática y tener client_DownloadFileCompleted iterate tht list para encontrar el siguiente archivo para descargar.

Espero que ayude, pero por favor publique más información si he entendido mal su pregunta.


Lo que he hecho es rellenar una cola que contenga todas mis URL, luego descargo cada elemento en la cola. Cuando no quedan elementos, puedo procesar todos los elementos. Me he burlado de algunos códigos a continuación. Tenga en cuenta que el código siguiente es para descargar cadenas y no archivos. No debería ser demasiado difícil modificar el código a continuación.

private Queue<string> _items = new Queue<string>(); private List<string> _results = new List<string>(); private void PopulateItemsQueue() { _items.Enqueue("some_url_here"); _items.Enqueue("perhaps_another_here"); _items.Enqueue("and_a_third_item_as_well"); DownloadItem(); } private void DownloadItem() { if (_items.Any()) { var nextItem = _items.Dequeue(); var webClient = new WebClient(); webClient.DownloadStringCompleted += OnGetDownloadedStringCompleted; webClient.DownloadStringAsync(new Uri(nextItem)); return; } ProcessResults(_results); } private void OnGetDownloadedStringCompleted(object sender, DownloadStringCompletedEventArgs e) { if (e.Error == null && !string.IsNullOrEmpty(e.Result)) { // do something with e.Result string. _results.Add(e.Result); } DownloadItem(); }

Editar: modifiqué tu código para usar una cola. No del todo seguro de cómo quería que el progreso funcione. Estoy seguro de que si desea que el progreso cubra todas las descargas, entonces puede almacenar el recuento de elementos en el método ''PopulateItemsQueue ()'' y usar ese campo en el método de cambio de progreso.

private Queue<string> _downloadUrls = new Queue<string>(); private void downloadFile(IEnumerable<string> urls) { foreach (var url in urls) { _downloadUrls.Enqueue(url); } // Starts the download btnGetDownload.Text = "Downloading..."; btnGetDownload.Enabled = false; progressBar1.Visible = true; lblFileName.Visible = true; DownloadFile(); } private void DownloadFile() { if (_downloadUrls.Any()) { WebClient client = new WebClient(); client.DownloadProgressChanged += client_DownloadProgressChanged; client.DownloadFileCompleted += client_DownloadFileCompleted; var url = _downloadUrls.Dequeue(); string FileName = url.Substring(url.LastIndexOf("/") + 1, (url.Length - url.LastIndexOf("/") - 1)); client.DownloadFileAsync(new Uri(url), "C://Test4//" + FileName); lblFileName.Text = url; return; } // End of the download btnGetDownload.Text = "Download Complete"; } private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) { if (e.Error != null) { // handle error scenario throw e.Error; } if (e.Cancelled) { // handle cancelled scenario } DownloadFile(); } 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; progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); }