多线程和C#中的循环计数器问题

时间:2015-07-25 18:47:32

标签: c# arrays multithreading

我目前正在使用Unity引擎和C#构建游戏,其中我生成了一个游戏世界。目前,它存在预定大小的字节[,],(在512和4096之间,因此总大小为4096×4096 = 16,700万个区块)。在实现一个方法的多线程变体,该方法随机地使用依赖于随机生成器的1或2填充我的数组时,我偶然发现了一个非常奇怪的问题。

这是我的代码:

void CellularAutomata()
    {
        int ThreadCount = Environment.ProcessorCount; //Amount of cores. 4 in my case
        ThreadCount *= 4; // Multiplying by 4 to get higher amount of threads.
        int ThreadWorkSizeX = WorldProps.Size.x / ThreadCount; //Divide map x size by threadcount
        int ThreadWorkSizeY = WorldProps.Size.y / ThreadCount; // same for y
        Thread[] Threads = new Thread[ThreadCount]; //create simple array
        //Main thread nog mee laten werken
        for (int i = 0; i < ThreadCount; i++) //for loop to create threads
        {
            UnityEngine.Debug.Log(i); // 0
            Threads[i] = new Thread(() => {
                UnityEngine.Debug.Log("Thread says " + (i)); // i is 1???
                //Doing i-1 to correct this, but give unpredictable results.
                for (int x = ( (i-1) * ThreadWorkSizeX); x < (( (i-1) * ThreadWorkSizeX) + ThreadWorkSizeX); x++)
                {
                    for (int y = ( (i-1) * ThreadWorkSizeY); y < (( (i-1) * ThreadWorkSizeY) + ThreadWorkSizeY); y++)
                    {
                        if (WorldProps.RandomGen.Next(0, 100) < CellProps.FillPercentage)
                        {
                            TileTypeXZ[x, y] = 2;
                        }
                        else
                        {
                            TileTypeXZ[x, y] = 1;
                        }
                    }
                }
            });
            //Inserting a debug.log here affects the results?
            Threads[i].Start();
        }

        //Joining up again with my threads.
        //(Yes i know, main thread not really doing anything yet, but i want this working first.)
        for (int p = 0; p < ThreadCount; p++)
        {
            Threads[p].Join();
        }

    }

这一切都是通过这种简单的方法完成的。它目前显然还没有完全实现Cellular Automata算法,但它必须在未来。我首先想让多线程随机填充我的地图。整个过程完全包含在这个方法中,除了我的WorldProps对象之外,没有任何能够影响这个方法的外部变量,它只包含一些与世界大小相关的变量等。这不是问题所在。

因此,我想分割我的世界,这是一个二维的字节数组,并为每个线程分配我的世界的一部分来填充。然而,在这里,我遇到了一些严重的问题。首先我还尝试在for循环后手动启动每个线程,但这导致我总是等于线程数量(在我的情况下为16),所以这是一个不行,但现在有这个奇怪的问题当我创建一个新的Thread对象,突然我的'i'变量增加1。通过使用(i-1)来纠正这个确实给了我一些结果,如果我修改for循环,(所以现在忽略i-1)但是当使用多个单独的线程时它停止工作。

出于某种原因放置Debug.Log(“Something”);在指定的行上影响我的线程正在创建的结果。

对不起我的英语不好,我还没掌握这门语言,因为我才17岁。

无论哪种方式,

有没有人在这里有任何线索为什么我有这个for循环计数器这些奇怪的问题? 非常感谢,

1 个答案:

答案 0 :(得分:3)

所有主题共享与for(int i=0; i < 10; i++) { new Thread(() => { Console.WriteLine(i); }) .Start(); } 相同的引用。使用临时变量

这是您有问题的代码

for(int i=0; i < 10; i++)
{
    var j = i;
    new Thread(() => {
        Console.WriteLine(j);
    })
    .Start();
}

将其更改为:

<form id="myContainer" method="post" action=[?]></form>

有关闭包的更多信息:http://www.codethinked.com/c-closures-explained