0

所以,我有一种“扫描”ftp 服务器的方法。首先它扫描根目录,并确定哪些内容是文件,哪些是文件夹,并将它们添加两个不同的集合(文件夹的字符串列表和文件的字符串,int 类型字典)。毕竟它自称。该方法在检查列表计数的 if...else 语句中运行。如果为零,则该方法扫描根文件夹。否则它应该将列表的第一个元素连接到 ftp 地址并检查该文件夹。这就是问题所在。每次我尝试执行该方法时,在第二次运行时(在根扫描结束后)它会抛出一个 InvalidOperation 异常,因为“集合已修改;枚举操作可能无法执行”。我怎样才能避免这种情况?

顺便说一下,这是代码:

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

1 回答 1

2

在 C# 中,在对基础集合进行结构修改后,枚举器无法继续。有两种常见的解决方法:

(1) 创建集合的副本(例如使用 ToArray())并枚举副本:

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

(2) 使用传统的 for 循环。仅当您仅附加到列表末尾时,这才是正确的:

for (var i = 0; i < directories.Count; ++i) {
    ... code which might append to directories
}
于 2013-06-22T17:15:14.380 回答