c# - 线程使用静态数据返回不同的值

标签 c# multithreading loops thread-state

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

相关文章:

c# - 如何调试 .NET Framework 源代码

c# - 使用泛型编写函数

javascript - 使用 jQuery 的单击事件停止循环

c# - "The remote certificate is invalid according to the validation procedure."使用 Gmail SMTP 服务器

c# - 读取从 "Scanners and Cameras"打开的文件会抛出 UnauthorizedAccessException

Java:带有 Callables 的 ExecutorService:在循环中重用同一个池?需要关机吗?

java - 如何在不同线程上同步部分方法

java - future 等待固定线程池在所有线程完成之前返回

python - 多处理写入python数组的函数循环

java - 从循环内调用的方法跳出 for 循环