C# 如何显示从FTP下载的进度

C# 如何显示从FTP下载的进度,c#,ftp,webclient,C#,Ftp,Webclient,我正在从FTP站点(异步)下载文件,需要更新进度条。我已经阅读了MS文档,其中说明如果WebClient类的GetWebRequest()为ovverriden,则可以执行此操作,因此“UseAssive”属性设置为“false”。我已经这样做了,但“DownloadProgressChanged”事件参数ProgressPercentage始终为=='0' 有人能告诉我如何让这个参数开始返回值吗 这是下载方法: FTPClient request = new FTPCl

我正在从FTP站点(异步)下载文件,需要更新进度条。我已经阅读了MS文档,其中说明如果WebClient类的GetWebRequest()为ovverriden,则可以执行此操作,因此“UseAssive”属性设置为“false”。我已经这样做了,但“DownloadProgressChanged”事件参数ProgressPercentage始终为=='0'

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

这是下载方法:

            FTPClient request = new FTPClient();
            request.Credentials = new NetworkCredential(user, password);
            request.DownloadProgressChanged += UpdateProgress;
            request.DownloadFileAsync(ftpepath,destinationpath);
这是FTPClient(我在这里重写GetWebRequest()):

如果有帮助,我会回电话:

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

useposive
用于“确定”在建立文件传输连接时谁充当服务器,因此它与传输的实际状态无关。请问你从哪里读到的

会是这样吗

  • 对于一个大文件,更改非常小,所以您看不到百分比更改了吗
  • 文件比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;
}
void UpdateProgress(对象发送方,下载progresschangedeventargs e){
设定进度(如进度百分比);
setText(例如ProgressPercentage.ToString()+“%”);
}
私有void setProgress(int progress){
if(dwnProgress.invokererequired){
调用(新操作(setProgress),progress);
返回;
}
dwnProgress.Value=进度;
}
私有void setText(字符串文本){
if(dwnprcnt.invokererequired){
调用(新操作(setText),文本);
返回;
}
dwnprcnt.Text=文本;
}

这将把setmethods排队到UI线程。

我想在上面的帖子上留下评论,但我太新了:(

关于重写web请求方法的MSDN参考:

但是,在回答OPs问题时,如果您的FTP服务器未设置为接受主动连接,则设置WebClient.useAnsive=false将不会有任何区别

编辑:我在我的项目上启用了System.Net.Tracing,尝试了被动和主动两种模式,不仅按预期完成了这两种工作…TotalBytes仍然是-1,所以我的想法是MSDN中的注释错了,或者我们遗漏了一些东西

下载的FileProgressChangedEventArgs包含接收的总字节数,如果您知道文件大小,可以自己计算

可能有更好的方法……但是我使用了一个快速的FtpWebRequest来获取文件大小,然后将其传递给DownloadProgressCallback方法来更新进度条

此外,上面的海报没有提到的是,更新进度方法必须调用该控件,因为DownloadFileAsync创建的线程正在调用该控件,并且您只能从创建该控件的线程更改该控件

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

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

请参见

,以显示您必须在单独的线程中调用该函数的进度,以便它不会阻止应用程序的UI(无论是for还是web页面)。
if (!myCheckBox.Dispatcher.CheckAccess())
{
    myCheckBox.Dispatcher.BeginInvoke(new Action(
    delegate()
    {
        myCheckBox.IsChecked = true;
    }
    ));
}
else
{
    myCheckBox.IsChecked = true;
}