【问题标题】:How Can I optimize my FTP Download using foreach() and ftpwebrequest?如何使用 foreach() 和 ftpwebrequest 优化我的 FTP 下载?
【发布时间】:2013-10-25 21:56:27
【问题描述】:

这是我正在使用的代码,它可以工作,但应用程序的 ftp 部分大约需要 5 分钟。

它们本身的文件不是太大,但我想优化应用程序,我觉得这是最好的起点。

我尝试下载 4 个特定文件。

这里是文件大小:

1 - ~48mb 2 - ~856k 3 - ~25mb 4 - ~49mb

// BEGIN FTP 
                WebClient request = new WebClient();
                request.Credentials =
                       new NetworkCredential(this.userNameRTF.Text,
                                                this.passRTF.Text);


                string[] ftpFile = new string[4];
                ftpFile[0] = "1";
                ftpFile[1] = "2";
                ftpFile[2] = "3";
                ftpFile[3] = "4"; 


                foreach(string s in ftpFile) 
                {
                    string ftpFileName = s;                        


                    byte[] fileData =
                            request.DownloadData(this.ftpHost
                                                   + this.ftpPath.Text + ftpFileName);                  

                    FileStream file =
                        File.Create(@"\\nas03\customerftp\" + custName.Text + @"\" + ftpFileName);

                    file.Write(fileData, 0, fileData.Length);

                    file.Close(); 
                } 

感谢您的帮助!

【问题讨论】:

  • 您是否输入了任何跟踪代码以真正查看哪些行在性能方面存在问题。您可以轻松地使用 StopWatch 类来帮助您。
  • 我不太确定什么是跟踪代码?我一直在自学,所以我确信我对 Visual Studio 所提供的一切都没有把握......
  • 另请注意,某些 FTP 服务器配置只能接受来自客户端 IP 的单个连接,因此在这种情况下,任何并行下载技巧都会失败。

标签: c# .net winforms ftp


【解决方案1】:

为什么不直接使用 API 处理这些:

WebClient request = new WebClient();
request.Credentials = new NetworkCredential(this.userNameRTF.Text,
                                            this.passRTF.Text);

string[] ftpFiles = new[] { "1", "2", "3", "4" };
var tasks = ftpFiles.Select(f => request.DownloadFileTaskAsync(
                         this.ftpHost + this.ftpPath.Text + ftpFileName,
                         @"\\nas03\customerftp\" + custName.Text + @"\" + ftpFileName));

Task.WaitAll(tasks.ToArray());

除了简化代码之外,这将同时下载和保存文件。

请注意,您可以通过将最后一行切换为:

使其成为异步方法(在 .NET 4.5/C# 5 中)
await Task.WhenAll(tasks);

鉴于您使用的是 .NET 4,您可以使用较旧的 DownloadFileAsync 方法:

WebClient request = new WebClient();
request.Credentials = new NetworkCredential(this.userNameRTF.Text,
                                            this.passRTF.Text);

var ftpFiles = new[] { "1", "2", "3", "4" };
var ce = new CountdownEvent(ftpFiles.Length);

request.DownloadFileCompleted += (o,e) => ce.Signal();

foreach(var file in ftpFiles)
    request.DownloadFileAsync(new Uri(this.ftpHost + this.ftpPath.Text + ftpFileName),
                         @"\\nas03\customerftp\" + custName.Text + @"\" + ftpFileName));

ce.Wait();

【讨论】:

  • 对不起,我是 c# 的初学者,我正在尽我所能自学,但有些事情让我无法理解。当我尝试使用您的示例时,我发现“System.net.WebClient”不包含“DownloadFileTaskAsync”的引用。我确实有“使用 System.Net”所以我认为我的设置是正确的,当然我可能遗漏了一些非常明显的东西。
  • @MitchellHamann 这是一个 .NET 4.5 方法 - 你使用的是什么框架版本?
  • 直到现在我才知道如何找到它,看起来像 .Net 4.0 我不确定我们的生产服务器是否使用 .NET 4.5。
  • 抱歉,花了这么长时间才回复您,我注意到 CountDownEvent 的另一个问题,它表示“找不到类型或命名空间”。我在顶部使用 System.Threading 进行了添加。不知道我还会错过什么
  • @MitchellHamann 这是CountdownEvent(小写D):msdn.microsoft.com/en-us/library/…
【解决方案2】:

您需要知道您的文件来自哪里、使用哪个带宽以及使用哪个带宽将它们带到哪里。从几行代码来看,除了您的互联网连接本身之外,似乎没有任何明显的瓶颈。只需计算使用您的带宽可以下载多少数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多