C#中的多线程和for循环计数器问题 [英] Issue with multithreading and for loop counter in C#

查看:548
本文介绍了C#中的多线程和for循环计数器问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently building a game using the Unity engine and C# in which i generate a gameworld. Currently it exists of a byte[,] of predetermined size, (between 512 and 4096, so for a total size of 4096x4096=16,7 million tiles). While implementing a multithreaded variant of a method which fills my array randomly with a 1 or a 2 dependent on a randomgenerator, i stumbled across a very weird problem.

这是我的代码:

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对象之外,没有其他变量可以影响此方法,WorldProps对象仅包含与世界大小相关的几个变量.这些不是这里的问题.

All this is done in this simple method. It currently obviously does not fully implement a Cellular Automata algorithm yet, but it has to in the future. I first wanted to get multithreaded random filling my map working. This whole process is fully contained in this method, and there are no external variables capable of affecting this method except my WorldProps object, which only houses a couple variables related to the size of the world and such. These ain't the problem here.

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

Therefore i wanted to split up my world, which is a two-dimensional array of bytes, and assign each thread a part of my world to fill. Here, however, i am stumbling upon some serious problems. First i also tried to manually start each thread after the for loop, but this resulted in i always being equal to the amount of threads (16 in my case), so this was a no go, but now there is this weird issue when i create a new Thread object, suddenly my 'i' variable is being incremented by one. Correcting this by using (i-1) does give me some results, if i modify the for loop, (so ignore the i-1 for now) but it stops working when using more than a single thread.

出于某种原因放置Debug.Log(某些东西");在指定的行上会影响我的线程正在创建的结果.

For some reason placing a Debug.Log ("Something"); on the specified line affects the results my threads are creating.

对不起,我的英语不好,因为我才17岁,所以我还没有掌握这种语言.

Sorry for my poor English, i don't yet master the language since i am just 17.

无论哪种方式,

这里有没有人知道为什么我在使用这个for循环计数器有这些怪异的问题? 非常感谢,

Has anyone here any clue why i am having these weird problems with this for loop counter? Many thanks,

推荐答案

所有线程共享对i的相同引用.使用临时变量

All threads share the same reference to i. Use a temporary variable

这是您有问题的代码

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

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

这篇关于C#中的多线程和for循环计数器问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆