如何修复“名称 'k' 在当前上下文中不存在”错误?

How to fix 'The name 'k' does not exist in the current context' error?

我只在 运行 解决方案正常时出现 System.IndexOutOfRangeException 错误,但在进入整个循环时一切正常。

我已经尝试捕获异常但没有成功。

private void button1_Click(object sender, EventArgs e)
        {
            for (int j = 0; j < jobs.Length; j++)
            {
                if (jobs[j].JobID == false)
                {
                    for (int k = 0; k < threads.Length; k++)
                    {
                        if (threads[k] != null)
                        {
                            if (!(threads[k].ThreadState == ThreadState.Stopped) | !(threads[k].ThreadState == ThreadState.Unstarted))
                            {
                                continue;
                            }
                        }

                        try
                        {
                            threads[k] = new Thread(() => CountUp("ftp://ftp.net" + jobs[j].FTPFolder, HomePath + jobs[j].localFolder, j));
                            threads[k].Name = "Thread " + j + "¦ ID: " + threads[k].ManagedThreadId.ToString();
                            jobs[j].JobID = true;
                            //threads[k].Start();
                            break;
                        }
                        catch (Exception exception)
                        {
                            Console.WriteLine(exception);
                            throw;
                        }

                    }
                }
            }
            StartThreads();
        }

如果 jobs[].JobID 为 false,我希望 threads[] 数组中的所有线程都被初始化。

下面是 CountUp() 方法:

        private void CountUp(string ftppath,string localFile, int jobsID)
        {
            //string conf="";
            NumberThreads++;
            //string ftpPath = "ftp://ftp.Rxsystems.net" + conf.Split('¦')[1];
            //string downloadPath = HomePath + conf.Split('¦')[0] + "\";

            string ftpPath = ftppath;
            string downloadPath = localFile;

            List<string> MSI = new List<string>(KD.FTP.Class.ListFiles(ftpPath,
                FTPuser, FTPpass));

            if (MSI.Count > 0)
            {
                KD.File.Class.Logger(Thread.CurrentThread.Name + ", " + MSI.Count + " Files in " + ftpPath, CurDir + "\log.txt");

                this.textBox1.AppendText(Thread.CurrentThread.Name + ", " + MSI.Count + " Files in " + ftpPath);
                //this.textBox1.AppendText("\n\r");
                int count = 0;
                foreach (string ftpFile in MSI)
                {
                    KD.FTP.Class.Download(ftpPath + ftpFile,downloadPath + "\" + ftpFile, FTPuser,FTPpass);
                    count++;
                    KD.File.Class.Logger(Thread.CurrentThread.Name + ", " + "Downloaded " + count + "/" + MSI.Count + " Files - " + ftpFile, CurDir + "\log.txt");
                    this.textBox1.AppendText(Thread.CurrentThread.Name + ", " + "Downloaded " + count + "/" + MSI.Count + " Files - " + ftpFile);
                    //this.textBox1.AppendText("\n\r");
                }
            }


            NumberThreads--;
            jobs[jobsID].JobID = false;
        }

下面初始化threads[]和jobs[]:

private void Form1_Load(object sender, EventArgs e)
        {
            Form1.CheckForIllegalCrossThreadCalls = false;

            if (File.Exists(CurDir + "\FTPpaths.config"))
            {
                foreach (string line in File.ReadAllLines(CurDir + "\FTPpaths.config"))
                {
                    if (!string.IsNullOrEmpty(line))
                    {
                        ConfigPaths.Add(line.Split('¦')[0] + "¦" + line.Split('¦')[1]);
                    }
                }

                if (ConfigPaths.Count > 0)
                {
                    jobs = new Jobs[ConfigPaths.Count];

                    for (int j = 0; j < ConfigPaths.Count; j++)
                    {
                        jobs[j] = new Jobs();
                        jobs[j].FTPFolder = ConfigPaths[j].Split('¦')[1];
                        jobs[j].localFolder = ConfigPaths[j].Split('¦')[0];
                        jobs[j].JobID = false;
                    }

                    threads = new Thread[jobs.Length];

                }


                timer1.Enabled = true;
            }
            else
            {
                Application.Exit();
            }
        }

据我所知,问题出在 j 变量上,该变量从闭包中捕获到传递给 new Thread 的委托中。众所周知,当实际委托执行在循环执行后引用状态中的变量时会出现问题,因此它应该有效地包含超出范围的 jobs.Length 值。要解决此问题,您需要在循环内引入一个局部变量以复制 j 值,然后使用此变量而不是 j 作为传递给 [= 的委托中 jobs 的索引17=]构造函数:

try
{
    var jobIdx = j;
    threads[k] = new Thread(() => CountUp("ftp://ftp.net" + jobs[jobIdx].FTPFolder, HomePath + jobs[jobIdx].localFolder, jobIdx));
    ...
    // other stuff

}
catch (Exception exception)
{
    Console.WriteLine(exception);
    throw;
}