如何显示FTP的下载进度

时间:2010-02-24 18:15:17

标签: c# ftp webclient

我正在从FTP站点(Async)下载文件,需要更新进度条。我已经阅读了MS文档,声明可以做到这一点是WebClient类的GetWebRequest()是ovverriden所以'UsePassive'属性被设置为'false'。我已经这样做但是'DownloadProgressChanged'事件参数ProgressPercentage总是=='0'。

有人可以告诉我如何让这个参数开始返回值吗?

这是下载方法:

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

这是FTPClient(我将覆盖GetWebRequest()):

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

如果有帮助我的回调:

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

2 个答案:

答案 0 :(得分:3)

UsePassive用于“确定”在进行文件传输连接时充当服务器的人员,因此它不应与传输的实际状态有任何关系。请问你在哪里看过这个?

可能是那个

  • 对于大文件,更改非常小,因此您没有看到百分比变化?
  • 该文件小于ftpwebrequests内部缓冲区,因此您可以在任何“更新”之前获取整个文件吗?

您可以在UpdateProgress中设置断点并查看任何e属性中的任何内容吗?

作为旁注,由于您正在下载文件异步,因此另一个线程用于实际下载。在您的事件方法中,您可能希望执行以下操作:

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

将把setmethods排队到UI线程。

答案 1 :(得分:2)

我想对上述帖子发表评论,但我太新了:(

在覆盖Web请求方法时引用MSDN:

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

但是,如果您的FTP服务器未设置为接受活动连接,那么在回答OP问题时,设置WebClient.UsePassive = false将没有任何区别。

编辑:我在我的项目上启用了System.Net.Tracing并尝试了被动模式和主动模式,并且不仅两个都按预期工作... TotalBytes仍然是-1所以我的想法是MSDN上的注释错误或我们遗失了什么

DownloadFileProgressChangedEventArgs确实包含收到的总字节数,如果你知道文件大小,你可以自己计算。

可能有更好的方法...但我使用快速FtpWebRequest获取文件大小,然后将其传递给DownloadProgressCallback方法以更新进度条。

上面的海报没有提到的是你的更新进度方法必须调用控件,因为它是由DownloadFileAsync创建的线程调用的,你只能从创建它的线程中更改控件。

您应该使用调度程序进行控制,例如

if (!myCheckBox.Dispatcher.CheckAccess())
{
    myCheckBox.Dispatcher.BeginInvoke(new Action(
    delegate()
    {
        myCheckBox.IsChecked = true;
    }
    ));
}
else
{
    myCheckBox.IsChecked = true;
}

请参阅http://msdn.microsoft.com/en-us/library/ms591206.aspx