Tarik
Tarik

Reputation: 81801

Show Progress Using WebClient Download

I am testing some features of WebClient class and I decided to see how DownloadProgressChanged works so I made up such code:

static void Main(string[] args)
{
  WebClient client = new WebClient();
  client.Proxy = null;
  client.BaseAddress = "ftp://ftp.xxxxxxx.com";
  CredentialCache cache = new CredentialCache();
  NetworkCredential credential = new NetworkCredential("userxxx", "passxxxx");
  client.Credentials = credential;
  client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
  Uri remoteFile;
  Uri.TryCreate("/public_html/folderxxxx/Pictures/Product/Resized/1.jpg", System.UriKind.Relative, out remoteFile);

  client.DownloadFileAsync(remoteFile, "1.jpg");
  System.Diagnostics.Process.Start("1.jpg");
  Console.ReadLine();
}

static void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
  Console.WriteLine(e.ProgressPercentage.ToString());
}

When I run this application, this is what I see as progress:

Console App Shows Progress

Looks nothing fancy. Ben Albahari suggest using new Thread instead of using Async method and this event handler is useful when you actually use Async method.

So how can I show Progress truly?

EDIT:

According to MSDN this should be done:

A passive FTP file transfer will always show a progress percentage of zero, since the server did not send the file size. To show progress, you can change the FTP connection to active by overriding the GetWebRequest virtual method:

Sample Code:

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

Which is what I did but the same problem happens:

enter image description here

Upvotes: 2

Views: 9264

Answers (3)

Dave Williams
Dave Williams

Reputation: 2246

There seem to be a lot of people asking this question.

So far as I can tell your server will only report back progress if it is set you allow active connections. It looks like PASV (passive FTP) can be enabled or disabled on the server. And the mode used should be determined by what the server is set to use and what is between server and client.

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

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

is mistaken or we are missing something.

http://compnetworking.about.com/cs/protocolsftp/g/bldef_pasv.htm

http://slacksite.com/other/ftp.html

http://fetchsoftworks.com/fetch/help/Contents/Concepts/ActiveAndPassive.html

So overriding the WebRequest method will make no difference if the server does not use active connections.

However... as you can see from your own command line readout it does report back the BytesReceived correctly.

Find out the file size and you're away...

I expect there is a more efficient method but... I used an FtpWebRequest to get the file size before downloading and then run DownloadFileAsync and pass the file size to the DownloadProgressCallback using:

Client.DownloadProgressChanges += (sender, e) => DownloadProgressCallback( fileSize, e)

Hope this helps :)

Upvotes: 1

Sam Axe
Sam Axe

Reputation: 33738

Did you read the documentation??

A passive FTP file transfer will always show a progress percentage of zero, since the server did not send the file size. To show progress, you can change the FTP connection to active by overriding the GetWebRequest virtual method:

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

Upvotes: 1

Cᴏʀʏ
Cᴏʀʏ

Reputation: 107606

From MSDN:

A passive FTP file transfer will always show a progress percentage of zero, since the server did not send the file size. To show progress, you can change the FTP connection to active by overriding the GetWebRequest virtual method.

Source

Upvotes: 3

Related Questions