简体   繁体   中英

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:

控制台应用程序显示进度

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:

在此处输入图片说明

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

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 :)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM