Mitchell Hamann
Mitchell Hamann

Reputation: 313

How Can I optimize my FTP Download using foreach() and ftpwebrequest?

Here is the code that I am using, it will work but the ftp portion of the application is taking around 5 minutes.

The files them selves are not too big, but I would like to optimize the application and I feel like this is the best place to start.

What I try to do is download the 4 particular files.

here are the file sizes:

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

Thank you for your help!

Upvotes: 1

Views: 1513

Answers (2)

Thorsten Schöning
Thorsten Schöning

Reputation: 3728

You need to tell where your files are coming from, with which bandwith, and where they are going with which bandwith. From the few lines of code it doesn't seem that there's any obvious bottleneck, other than your internet connection itself. Simply calculate how much data can be downloaded using your bandwith.

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564831

Why not just handle these using the 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());

In addition to simplifying the code, this will download and save the files concurrently.

Note that you can make this an asynchronous method (in .NET 4.5/C# 5) by switching the last line to:

await Task.WhenAll(tasks);

Given that you're using .NET 4, you could use the older DownloadFileAsync method:

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

Upvotes: 4

Related Questions