如何修复“名称 '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;
}
我只在 运行 解决方案正常时出现 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;
}