Pregunta

VS 2008 SP1

Estoy usando el cliente web para descargar algunos archivos de forma asincrónica.

Tengo 5 archivos para descargar.

Sin embargo, quiero monitorear cada descarga y establecer el estado del usuario como el nombre del archivo, por lo que en el ProgressCompletedEvent puedo verificar el estado del usuario para ver qué archivo se ha completado.

Es un breve fragmento de código de lo que estoy tratando de hacer.

// This function will be called for each file that is going to be downloaded.
// is there a way I can set the user state so I know that the download 
// has been completed 
// for that file, in the DownloadFileCompleted Event? 
private void DownloadSingleFile()
{
    if (!wb.IsBusy)
    {        
        //  Set user state here       
        wb.DownloadFileAsync(new Uri(downloadUrl), installationPath);
    }
}


void wb_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    Console.WriteLine("File userstate: [ " + e.UserState + " ]");   
}

void wb_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    Console.WriteLine("File userstate: [ " + e.UserState + " ]");   

    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());

}
¿Fue útil?

Solución

Puede pasar cualquier objeto como argumento tercer a la llamada DownloadFileAsync (), y lo recuperará como userState. En su caso, simplemente podría pasar su nombre de archivo.

Otros consejos

¿Qué tal algo como esto?

private void BeginDownload(
    string uriString,
    string localFile,
    Action<string, DownloadProgressChangedEventArgs> onProgress,
    Action<string, AsyncCompletedEventArgs> onComplete)
{
    WebClient webClient = new WebClient();

    webClient.DownloadProgressChanged +=
        (object sender, DownloadProgressChangedEventArgs e) =>
            onProgress(localFile, e);

    webClient.DownloadFileCompleted +=
        (object sender, AsyncCompletedEventArgs e) =>
            onComplete(localFile, e);

    webClient.DownloadFileAsync(new Uri(uriString), localFile);
}

En su código de llamada, podría tener un código como este:

Action<string, DownloadProgressChangedEventArgs> onProgress =
    (string localFile, DownloadProgressChangedEventArgs e) =>
    {
        Console.WriteLine("{0}: {1}/{2} bytes received ({3}%)",
            localFile, e.BytesReceived,
            e.TotalBytesToReceive, e.ProgressPercentage);
    };

Action<string, AsyncCompletedEventArgs> onComplete =
    (string localFile, AsyncCompletedEventArgs e) =>
    {
        Console.WriteLine("{0}: {1}", localFile,
            e.Error != null ? e.Error.Message : "Completed");
    };

downloader.BeginDownload(
    @"http://url/to/file",
    @"/local/path/to/file",
    onProgress, onComplete);

Si no le importa hacerlo demasiado reutilizable, puede deshacerse de las funciones pasadas y escribir las expresiones lambda directamente en su código:

private void BeginDownload(string uriString, string localFile)
{
    WebClient webClient = new WebClient();

    webClient.DownloadProgressChanged +=
        (object sender, DownloadProgressChangedEventArgs e) =>
            Console.WriteLine("{0}: {1}/{2} bytes received ({3}%)",
                localFile, e.BytesReceived,
                e.TotalBytesToReceive, e.ProgressPercentage);

    webClient.DownloadFileCompleted +=
        (object sender, AsyncCompletedEventArgs e) =>
            Console.WriteLine("{0}: {1}", localFile,
                e.Error != null ? e.Error.Message : "Completed");

    webClient.DownloadFileAsync(new Uri(uriString), localFile);
}

Llamado dos veces, esto le dará resultados como este

/ ruta / a / archivo1: 265/265 bytes recibidos (100%)
/ ruta / a / archivo1: Completado
/ ruta / a / archivo2: 2134/2134 bytes recibidos (100%)
/ ruta / a / archivo2: Completado

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top