Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 多线程和向新线程传递数据_C#_Multithreading - Fatal编程技术网

C# 多线程和向新线程传递数据

C# 多线程和向新线程传递数据,c#,multithreading,C#,Multithreading,我正在编写的应用程序有一些问题。它的工作是用线程解决一个迷宫。一个线程开始,对于每个分支,它调用另一个类中的静态方法,传递另一个线程需要的参数,然后为每个路径启动线程。我的输出都搞砸了,我不确定这是多线程问题还是引用问题。下面是一些代码,每个线程都有一个Explorer类的新实例: 这是每个线程的运行方法: public void Explore() { while (ImDone == false) { Move(); if (ActualPos

我正在编写的应用程序有一些问题。它的工作是用线程解决一个迷宫。一个线程开始,对于每个分支,它调用另一个类中的静态方法,传递另一个线程需要的参数,然后为每个路径启动线程。我的输出都搞砸了,我不确定这是多线程问题还是引用问题。下面是一些代码,每个线程都有一个Explorer类的新实例:

这是每个线程的运行方法:

public void Explore()
{
    while (ImDone == false)
    {
        Move();
        if (ActualPosition[0] != Labyrinth.ExitPoint[0] || 
            ActualPosition[1] !=   Labyrinth.ExitPoint[1]) //I'm not at the end..
        continue;

        PrintMyStatus(); //Print in the console my parents and my complete route..
        break;
    }
这是移动方法:

这是创建线程的类:

public static class ExplorationManager
{
    public static void ExplorerMaker(List<int[]> validPaths, List<string> myParents, string[,] myExplorationMap, List<int[]> myPositions, int ID)
    {
        foreach (var thread in validPaths.Select
            (path => new Explorer(myParents, path, myExplorationMap, myPositions,ID)).
            Select(explorer => new Thread(explorer.Explore)))
        {
            thread.Name = "Thread of " + ID + " generation"; 
            thread.Start(); //For each Path in Valid paths, create a new instance of Explorer and assign a thread to it.
        }
    }
}
以及返回有效路径的方法

    private List<int[]> CheckSurroundings()
    {

        var validPaths = new List<int[]>();
        var posX = ActualPosition[0];
        var posY = ActualPosition[1];

        for (var dx = -1; dx <= 1; dx++)
        {
            if (dx == 0 || (posX + dx) < 0 || (posX + dx) >= Labyrinth.Size ||
                MyExplorationMap[posX + dx, posY] == "1") continue;
            var tempPos = new int[2];
            tempPos[0] = posX + dx;
            tempPos[1] = posY;
            validPaths.Add(tempPos);
        }

        for (var dy = -1; dy <= 1; dy++)
        {
            if (dy == 0 || (posY + dy) < 0 || (posY + dy) >= Labyrinth.Size ||
                MyExplorationMap[posX, posY + dy] == "1") continue;
            var tempPos = new int[2];
            tempPos[0] = posX;
            tempPos[1] = posY + dy;
            validPaths.Add(tempPos);
        }
        //This method checks up, down, left, right and returns the posible routes as `int[]` for each one
        return validPaths;
    }
CheckEnvironment使用通过构造函数传递给子级的深度副本来验证他可以采取的路由。它并不打算改变父母的副本,因为他现在在迷宫的另一条道路上。子级只需要更新通过构造函数传递的信息,直到它们分离为止。而且每个孩子都必须独立于其他孩子。这就是我想做的。但我不确定出了什么问题,可能是并发问题?请帮忙。如果您还需要什么,请告诉我

为您的更新编辑:


myExplorationMap是原始勘探地图的深层副本。在Explorer构造函数中将位置设置为1,这将更新所有子线程共享的副本,但不会更新父线程中的原始MyExplorationMap属性。只有子线程才知道访问了此位置。我假设这是在CheckEnvironment方法中使用的?

只是一个旁注:除非绝对必要,否则请不要在标题中包含标签。您已经将问题标记为C,没有必要在标题中说C。我已经查看了代码,但我并不清楚您遇到了什么问题。你说你的输出都搞砸了是什么意思?你的输出是什么,你期望它是什么,还有其他相关的代码吗?定义所有的混乱。运行此代码时实际发生了什么?刚刚编辑了问题。我可以发布所需的任何其他代码,只需发布我认为给出问题的代码,以便使问题变得更小。@lik我将立即提供任何其他信息。为了答案,我更新了问题。。。我真的很感谢你的帮助!任何其他信息请告诉我。每个线程都有自己的有效路径副本,因为它是本地的,我只传递一个包含孩子必须开始的路径的列表,所以它不应该与他的父母交互。他只需要知道历史,直到它被创造的那一刻。之后他们就独立了,这是完全正确的。我的意图就是这样。CheckEnvironment使用通过构造函数传递给子级的深度副本来验证他可以采取的路由。它并不打算改变父母的副本,因为他现在在迷宫的另一条道路上。子级只需要更新通过构造函数传递的信息,直到它们分离为止。而且每个孩子都必须独立于其他孩子。这就是我想做的。但我不确定出了什么问题,可能是并发问题?请帮忙。如果你还需要什么,请告诉我。只有在你有两个后代线程(可能是两个或三个子线程)最终相遇之前,这才是正确的。它们永远不会运行与共享父级相同的路径,但两个独立的子代树仍有可能多次重新遍历同一区域。如果它们是子代的独立树,则它们可以遍历其他路径,只要以前没有在其自己的线程树中访问过这些路径,因为解决同一个迷宫有多种方法,而且我假设最终每个线程要么没有可能的路径,要么会到达出口,这就是我传递MyExplorationMap副本的原因。基于此代码,我的假设正确吗?如果它是正确的,为什么每个线程移动的位置数据会被破坏?一切正常吗?还需要其他信息吗?我真的很难解决这个问题。
public static class ExplorationManager
{
    public static void ExplorerMaker(List<int[]> validPaths, List<string> myParents, string[,] myExplorationMap, List<int[]> myPositions, int ID)
    {
        foreach (var thread in validPaths.Select
            (path => new Explorer(myParents, path, myExplorationMap, myPositions,ID)).
            Select(explorer => new Thread(explorer.Explore)))
        {
            thread.Name = "Thread of " + ID + " generation"; 
            thread.Start(); //For each Path in Valid paths, create a new instance of Explorer and assign a thread to it.
        }
    }
}
    private List<int[]> CheckSurroundings()
    {

        var validPaths = new List<int[]>();
        var posX = ActualPosition[0];
        var posY = ActualPosition[1];

        for (var dx = -1; dx <= 1; dx++)
        {
            if (dx == 0 || (posX + dx) < 0 || (posX + dx) >= Labyrinth.Size ||
                MyExplorationMap[posX + dx, posY] == "1") continue;
            var tempPos = new int[2];
            tempPos[0] = posX + dx;
            tempPos[1] = posY;
            validPaths.Add(tempPos);
        }

        for (var dy = -1; dy <= 1; dy++)
        {
            if (dy == 0 || (posY + dy) < 0 || (posY + dy) >= Labyrinth.Size ||
                MyExplorationMap[posX, posY + dy] == "1") continue;
            var tempPos = new int[2];
            tempPos[0] = posX;
            tempPos[1] = posY + dy;
            validPaths.Add(tempPos);
        }
        //This method checks up, down, left, right and returns the posible routes as `int[]` for each one
        return validPaths;
    }