2010-02-24 120 views
5

我正在从FTP站点(异步)下载文件并需要更新进度栏。我已阅读MS文档,指出可以完成的是WebClient类的GetWebRequest()是ovverriden,因此'UsePassive'属性设置为'false'。我做了这个,但'DownloadProgressChanged'事件参数ProgressPercentage总是=='0'。如何从FTP显示下载进度

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

这是下载方法:

  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() + "%"; 
     } 
+0

表明你要调用的函数在一个单独的线程,因此不会阻止该应用程序的UI是否它或网页的进展。 – 2010-02-24 18:55:14

回答

3

UsePassive用于在进行文件传输连接时“确定”谁起到服务器的作用,所以它不应该与转移的实际状态有任何关系。我可以问问你在哪里看过这个?

难道

  • 的变化是非常小的一个大的文件,所以你看不到percentagechanged?
  • 该文件小于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线程来代替。

2

我想离开上述职位的评论,但我太新:(

参考MSDN上重写Web请求方法:

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

在回答

但是到OPS如果问题FTP服务器未设置为接受主动连接,然后设置WebClient.UsePassive = false将没有什么区别

编辑:我启用System.Net.Tracing在我的项目,试图被动的d活动模式,并且不仅两者都按预期工作... 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