NeverJr
NeverJr

Reputation: 305

how can avoid the InvalidOperationException in the following method?

So, I have a method which "scan" an ftp server. At first it scans the root, and determines which content is file and which one is folder, and add them two different collections(string list for folders and a string,int type dictionary for the files). And after all it calls itself. The method runs in an if...else statement which checks the list's count. If it's zero, the method scans the root folder. Else it should concat the list's first element to the ftp address and check that folder. And here's the problem. Every time I try to execute the method, at the second run(after the scanning of root was ended) it throws an InvalidOperation Exception because "the collection was modified; enumeration operation may not execute". How can I avoid this?

Here's the code by the way:

internal void ListFilesOnServer()
    {
        ArrayList files = new ArrayList();
        if (directories.Count == 0)
        {
            try
            {
                FtpWebRequest ftpwrq = (FtpWebRequest)WebRequest.Create(server);
                ftpwrq.Credentials = new NetworkCredential(user, passw);
                ftpwrq.Method = WebRequestMethods.Ftp.ListDirectory;
                ftpwrq.KeepAlive = false;
                FtpWebResponse fresponse = (FtpWebResponse)ftpwrq.GetResponse();
                StreamReader sr = new StreamReader(fresponse.GetResponseStream());
                string temp = "";
                while ((temp = sr.ReadLine()) != null)
                {
                    files.Add(temp);
                }
                temp = String.Empty;
                sr.Close();
                fresponse.Close();
                DirOrFile(files);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        else
        {
            foreach (string file in directories)
            {
                try
                {
                    FtpWebRequest ftpwrq = (FtpWebRequest)WebRequest.Create(server+"/"+file);
                    ftpwrq.Credentials = new NetworkCredential(user, passw);
                    ftpwrq.Method = WebRequestMethods.Ftp.ListDirectory;
                    ftpwrq.KeepAlive = false;
                    FtpWebResponse fresponse = (FtpWebResponse)ftpwrq.GetResponse();
                    StreamReader sr = new StreamReader(fresponse.GetResponseStream());
                    string temp = "";
                    while ((temp = sr.ReadLine()) != null)
                    {
                        files.Add(temp);
                    }
                    temp = String.Empty;
                    sr.Close();
                    fresponse.Close();
                    DirOrFile(files);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
        }
        level = 1;
        ListFilesOnServer();
    }

Upvotes: 0

Views: 368

Answers (1)

ChaseMedallion
ChaseMedallion

Reputation: 21764

In C#, an enumerator can't continue after the underlying collection has been structurally modified. There are two common ways around this:

(1) Create a copy of the collection (e. g. with ToArray()) and enumerate over the copy:

foreach (string file in directories.ToArray()) {
    ...
}

(2) Use a traditional for-loop. This will only be correct if you are only appending to the end of the list:

for (var i = 0; i < directories.Count; ++i) {
    ... code which might append to directories
}

Upvotes: 2

Related Questions