2010-02-24 21 views
5

Estoy descargando un archivo desde un sitio FTP (Async) y necesito actualizar una barra de progreso. He leído la documentación de MS que indica que esto se puede hacer es que GetWebRequest() de la clase WebClient esté ovverriden, por lo que la propiedad 'UsePassive' se establece en 'false'. He hecho esto pero el argumento del evento 'DownloadProgressChanged' ProgressPercentage siempre es == '0'.Cómo mostrar el progreso de la descarga desde FTP

¿Puede alguien decirme cómo obtener este argumento para comenzar a devolver los valores?

Este es el método de descarga:

  FTPClient request = new FTPClient(); 
      request.Credentials = new NetworkCredential(user, password); 
      request.DownloadProgressChanged += UpdateProgress; 
      request.DownloadFileAsync(ftpepath,destinationpath); 

Ésta es la FtpClient (donde estoy preponderantes con GetWebRequest()):

class FTPClient : WebClient 
    { 
     protected override WebRequest GetWebRequest(System.Uri address) 
     { 
      FtpWebRequest req = (FtpWebRequest) base.GetWebRequest(address); 
      req.UsePassive = false; 
      return req; 
     } 
    } 

Y mi devolución de llamada si ayuda:

void UpdateProgress(object sender, DownloadProgressChangedEventArgs e) 
     { 
      dwnProgress.Value = e.ProgressPercentage; 
      dwnprcnt.Text = PercentProgress.ToString() + "%"; 
     } 
+0

Para mostrar el progreso que tiene que llamar a la función en un hilo separado para que no bloquee la interfaz de usuario de la aplicación si su para o página web. –

Respuesta

3

UsePassive se usa para "determinar" quién actúa como servidor cuando se realiza la conexión para la transferencia de archivos , por lo que no debería tener nada que ver con el estado real de la transferencia. ¿Puedo preguntar dónde has leído esto?

Podría ser que

  • el cambio es muy pequeño para un archivo de gran tamaño, por lo que no ven la percentagechanged?
  • que el archivo es más pequeño que el búfer interno de ftpwerequests para que pueda obtener todo el archivo antes de cualquier "actualización"?

¿Puede establecer un punto de interrupción en UpdateProgress y ver algo en cualquiera de las propiedades de e?

Y como nota al margen, dado que está descargando el archivo de forma asíncrona, se usa otro hilo para la descarga real. En el método de evento es probable que desee hacer algo como esto:

void UpdateProgress(object sender, DownloadProgressChangedEventArgs e) { 
    setProgress(e.ProgressPercentage); 
    setText(e.ProgressPercentage.ToString() + "%"); 
} 

private void setProgress(int progress){ 
    if (dwnProgress.InvokeRequired) { 
     dwnProgress.Invoke(new Action<int>(setProgress), progress); 
     return; 
    } 
    dwnProgress.Value = progress; 
} 

private void setText(string text) { 
    if (dwnprcnt.InvokeRequired) { 
     dwnprcnt.Invoke(new Action<string>(setText), text); 
     return; 
    } 
    dwnprcnt.Text = text; 
} 

Qué pondrá en cola los setmethods al hilo de interfaz de usuario en su lugar.

2

quería dejar un comentario en el post anterior, pero estoy demasiado nuevo :(

referencia a MSDN en la sustitución del método solicitud Web:

http://msdn.microsoft.com/en-US/library/system.net.webclient.downloadprogresschanged(v=vs.80).aspx

Sin embargo, en respuesta a los PO pregunta si su servidor FTP no está configurado para aceptar conexiones activas, entonces la configuración de WebClient.UsePassive = false no hará ninguna diferencia.

EDITAR: habilité System.Net.Tracing en mi proyecto e intenté tanto pasivo como d modos activos y no solo funcionan como se espera ... TotalBytes sigue siendo -1 entonces mi pensamiento es la nota en MSDN equivocada o nos falta algo

DownloadFileProgressChangedEventArgs contiene el total de bytes recibidos y si conoce el tamaño del archivo que puede calcular usted mismo.

Es probable que haya una manera mejor ... Pero usé FtpWebRequest rápido para obtener el tamaño del archivo y luego pasé esto al método DownloadProgressCallback para actualizar la barra de progreso.

También lo que el cartel anterior no mencionó es que su método de progreso de actualización debe invocar el control porque lo está llamando el subproceso creado por DownloadFileAsync y solo puede cambiar un control del subproceso que lo creó.

Debe usar el despachador para el control, p.

if (!myCheckBox.Dispatcher.CheckAccess()) 
{ 
    myCheckBox.Dispatcher.BeginInvoke(new Action(
    delegate() 
    { 
     myCheckBox.IsChecked = true; 
    } 
    )); 
} 
else 
{ 
    myCheckBox.IsChecked = true; 
} 

Ver http://msdn.microsoft.com/en-us/library/ms591206.aspx

Cuestiones relacionadas