2

我正在制作一个在提取数据的大目录上运行的工具,并为每个语言代码(目录中的第一级文件)启动一个线程。我添加了一个循环,该循环阻止线程添加到数据库中,直到所有线程都完成为止,因为没有它,该工具将陷入死锁。但是,在测试此数据时,即使测试数据是静态的,数据库也会存储错误数量的语言。例如,我有 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
            }
        }
4

1 回答 1

2

首先也是最重要的:制作路径的本地副本并将其传递给线程而不是for循环变量。关闭循环变量被认为是有害的。

我不知道为什么你会得到一个索引超出范围异常,但你也可以通过使用foreach-loop 来避免这种情况。

//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);
}

第二:在线程上使用Join而不是使用一些自定义等待代码。

// wait for all threads to complete before proceeding
foreach (Thread thread in threads)
{
    thread.Join();
}

最后,确保数据库没有争用。如果没有有关其HBScanner作用的更多信息,就很难说其他可能导致此问题的原因。

于 2013-02-05T16:00:44.360 回答