使用WebClient下载显示进度

时间:2012-03-23 23:38:20

标签: c# webclient

我正在测试WebClient类的一些功能,我决定看看DownloadProgressChanged是如何工作的,所以我编写了这样的代码:

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

当我运行此应用程序时,这就是我所看到的进步:

Console App Shows Progress

看起来没什么特别的。 Ben Albahari建议使用新的Thread而不是使用Async方法,当您实际使用Async方法时,此事件处理程序非常有用。

那么我怎样才能真正展现进步?

修改

根据MSDN,应该这样做:

  

被动FTP文件传输将始终显示进度百分比   零,因为服务器没有发送文件大小。为了显示进度,   您可以通过覆盖来将FTP连接更改为活动状态   GetWebRequest虚拟方法:

示例代码:

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

我做了哪件事但发生了同样的问题:

enter image description here

3 个答案:

答案 0 :(得分:3)

来自MSDN:

  

由于服务器未发送文件大小,因此被动FTP文件传输将始终显示零进度百分比。要显示进度,可以通过覆盖GetWebRequest虚拟方法将FTP连接更改为活动。

Source

答案 1 :(得分:1)

你读过documentation ??

吗?
  

被动FTP文件传输将始终显示进度百分比   零,因为服务器没有发送文件大小。为了显示进度,   您可以通过覆盖来将FTP连接更改为活动状态   GetWebRequest虚拟方法:

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

答案 2 :(得分:1)

似乎有很多人在问这个问题。

据我所知,只要设置了允许活动连接,服务器将只报告进度。看起来可以在服务器上启用或禁用PASV(被动FTP)。使用的模式应该由服务器设置使用的内容以及服务器和客户端之间的内容决定。

编辑:我在我的项目上启用了System.Net.Tracing并尝试了被动模式和主动模式,不仅两者都按预期工作... TotalBytes仍为-1所以我的想法是关于MSDN的说明

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

错了,或者我们遗漏了什么。

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

如果服务器不使用活动连接,那么重写WebRequest方法将没有任何区别。

但是......正如您从自己的命令行读数中看到的那样,它会正确地报告BytesReceived。

找出文件大小,你就离开......

我希望有一个更有效的方法,但是...我在下载之前使用FtpWebRequest获取文件大小,然后运行DownloadFileAsync并使用以下命令将文件大小传递给DownloadProgressCallback:

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

希望这会有所帮助:)