我正在制作一个在大型目录上运行的工具,提取数据并为每个语言代码(目录中的第一层文件)启动一个线程。我添加了一个循环,阻止线程添加到数据库,直到所有线程都完成,因为如果没有它,该工具就会陷入死锁。然而,在测试这些数据时,即使测试数据是静态的,数据库也会存储错误数量的语言。例如,我有 67 种语言,但我的数据库中只有 48 种。我认为问题可能是我在线程停止之前停止程序继续运行的循环可能会被破坏,即。它会在所有线程停止之前将文件添加到数据库,从而在此过程中丢失语言。我不认为有人遇到过类似的问题或知道解决这个问题的方法吗?谢谢。
//get the languages from the folders
string[] filePaths = Directory.GetDirectories(rootDirectory);
for (int i = 0; i < filePaths.Length; i++)
{
string LCID = filePaths[i].Split('\\').Last();
Console.WriteLine(LCID);
//go through files in each folder and sub-folder with threads
Thread t1 = new Thread(() => new HBScanner(new DirectoryInfo(filePaths[i - 1])).HBscan());
t1.Start();
threads.Add(t1);
}
// wait for all threads to complete before proceeding
foreach (Thread thread in threads)
{
while (thread.ThreadState != ThreadState.Stopped)
{
//wait
}
}
最佳答案
首先也是最重要的:创建路径的本地副本并将其传递到线程而不是 for 循环变量中。 Closing over the loop variable is considered harmful.
我不知道为什么会出现索引超出范围异常,但您也可以通过使用 foreach
循环来避免这种情况。
//get the languages from the folders
string[] filePaths = Directory.GetDirectories(rootDirectory);
foreach(string filePath in filePaths)
{
Console.WriteLine(filePath.Split('\\').Last());
string tmpPath = filePath; // <-- local copy
//go through files in each folder and sub-folder with threads
Thread t1 = new Thread(() => new HBScanner(new DirectoryInfo(tmpPath)).HBscan());
t1.Start();
threads.Add(t1);
}
第二个:use Join
on the threads而不是使用一些自定义等待代码。
// wait for all threads to complete before proceeding
foreach (Thread thread in threads)
{
thread.Join();
}
最后,确保数据库不存在争用。如果没有关于 HBScanner
功能的更多信息,就很难说出可能导致此问题的任何其他信息。
关于c# - 线程使用静态数据返回不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14710799/