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() + "%";
}
The ftp command uses the File Transfer Protocol (FTP) to transfer files between the local host and a remote host or between two remote hosts. Remote execution of the ftp command is not recommended. The FTP protocol allows data transfer between hosts that use dissimilar file systems.
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
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.
I wanted to leave a comment to the above post but I am too new :(
Reference to MSDN on overriding the web request method:
http://msdn.microsoft.com/en-US/library/system.net.webclient.downloadprogresschanged(v=vs.80).aspx
However in answer to the OPs question if your FTP server is not set to accept active connections then setting WebClient.UsePassive = false will make no difference.
EDIT: I enabled System.Net.Tracing on my project and tried both passive and active modes and not only do both work as expected... TotalBytes is still -1 so my thinking is the note on MSDN in mistaken or we are missing something
The DownloadFileProgressChangedEventArgs do contain the total bytes received and if you know the file size you can calculate yourself.
There is likely a better way... But I used a quick FtpWebRequest to get the file size and then pass this to the DownloadProgressCallback method to update the progress bar.
Also what the above poster failed to mention is that your update progress method must invoke the control because it is being called by the thread created by DownloadFileAsync and you can only change a control from the thread that created it.
You should use the dispatcher for the control e.g.
if (!myCheckBox.Dispatcher.CheckAccess())
{
myCheckBox.Dispatcher.BeginInvoke(new Action(
delegate()
{
myCheckBox.IsChecked = true;
}
));
}
else
{
myCheckBox.IsChecked = true;
}
See http://msdn.microsoft.com/en-us/library/ms591206.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With