tags:

views:

371

answers:

1

Hey All..

I am downloading a file from an FTP site (Async) and need to update a progress bar. I have read MS documentation that states that this can be done is the WebClient class's GetWebRequest() is ovverriden so the 'UsePassive' property is set to 'false'. I have done this but 'DownloadProgressChanged' event argument ProgressPercentage is always == '0'.

Can someone tell me how to get this argument to start returning values?

This is the download method:

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

This is the FTPClient (where i am overriding GetWebRequest()):

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

And my Callback if it helps:

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

UsePassive is used to "determine" who acts as the server when the connection for the file transfer is made, so it should not have anything to do with the actual status of the transfer. May I ask where you have read this?

Could it be that

  • the change is very small for a large file, so you don't see the percentagechanged?
  • that the file is smaller than ftpwebrequests internal buffer so you get the whole file before any "update"?

Can you set a breakpoint in UpdateProgress and see anything in any of e's properties?

And as a side note, since you are downloading the file async, another thread is used for the actual download. In your event method you probably want to do something like this:

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

Which will queue the setmethods to the UI thread instead.

Patrick