我正在制作一个在大型目录上运行的工具,该目录提取数据并根据语言代码(目录中的第一级文件)启动一个线程。我添加了一个循环,阻止线程添加到数据库,直到所有线程都完成,因为该工具在没有它的情况下进入死锁状态。但是,在测试此数据时,即使测试数据是静态的,DB也会存储错误数量的语言。例如,我有67种语言,但我的数据库中只有48种语言。我认为问题可能是我的循环停止程序在线程停止之前继续可能会被打破,即。它是在所有线程停止之前向DB添加文件,从而在此过程中丢失语言。我不认为有人遇到过类似的问题或知道解决这个问题的方法吗?感谢。
//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
}
}
答案 0 :(得分:2)
首先:制作路径的本地副本并将其传递给线程而不是for-loop变量。 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
做什么的进一步信息,就很难说出可能导致此问题的原因。