我在編寫一個應用程序時遇到了一些問題。這是工作是使用線程解決迷宮。一個線程開始,並且對於每個分支它調用另一個類中的靜態方法,傳遞另一個線程需要的參數,然後爲每個路徑啓動線程。我的輸出都搞砸了,我不確定這是多線程問題還是與引用有關的問題。下面是一些代碼(每個線程都被賦予一個Explorer
類的新實例):多線程並將數據傳遞到新線程
這是每個線程的Run()
方法:
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;
}
這是Move()
方法:
List<int[]> validPaths = CheckSurroundings(); //returns a list of paths
switch (validPaths.Count)
{
case 0:
ImDone = true; //No more routes available
break;
case 1:
MarkMyPosition(validPaths); //Change internal variables to the only new path
break;
default:
lock(this) //As this involves thread creating I locked it..
{
//Creating deep copies of my "History" so my childs can have them..
List<int[]> DCValidPaths = DeepCopy(validPaths);
List<string> DCMyParents = DeepCopy(MyParents);
string[,] DCMyExplorationMap = DeepCopy(MyExplorationMap);
List<int[]> DCMyPositions = DeepCopy(MyPositions);
foreach (var path in validPaths)
{
DCMyParents.Add(Thread.CurrentThread.Name); //Adding myself as a parent
ExplorationManager.ExplorerMaker(
DCValidPaths,
DCMyParents,
DCMyExplorationMap,
DCMyPositions,
ID); //Threads are created in the static class
}
}
break;
}
我的DeepCopy()
方法正在使用的是在this接受答案的問題。需要其他任何信息我將非常樂意提供以解決問題。在此先感謝您的幫助。編輯:我的問題基本上在於:我在Thread.Start()
子句中有一個OutOfMemoryException
和由線程顯示的路徑包含損壞的數據(不正確的位置)。我測試了CheckSurroundings()
方法,到目前爲止只返回正確的位置(迷宮包含在一個二維字符串數組中)。
這是Explorer
類的構造函數:
public Explorer(List<string> myParents, int[] actualPosition, string[,] myExplorationMap,
List<int[]> myPositions, int ID)
{
//Here I pass the data specified in Move();
MyParents = myParents;
ActualPosition = actualPosition;
MyExplorationMap = myExplorationMap;
MyPositions = myPositions;
this.ID = ID + 1; //An ID for reference
//Marking position in my map with "1" so I know I've been here already,
//and adding the position given to my list of positions
MyExplorationMap[ActualPosition[0], ActualPosition[1]] = "1";
MyPositions.Add(DeepCopy(ActualPosition));
}
這是類創建線程:
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.
}
}
}
,並且該方法返回ValidPaths
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;
}
CheckSurroundings使用傳遞給孩子的深層副本(通過構造uctor)驗證他可以採取的路線。它並不打算改變父母的副本,因爲他現在正處於迷宮的另一條路上。孩子只需要更新信息(通過構造函數傳遞)直到他們「分離」的點。而且每個孩子都必須獨立於其他孩子。這就是我想要做的。但我不確定有什麼問題,可能是併發問題?請幫忙。如果你需要其他東西,請告訴我。 -
**只是旁註:**請不要在標題中加入標籤,除非絕對必要。您已經將問題標記爲C#,標題中不需要說C#。 – Kiril
@李克羅傑羅傑,謝謝。 –
我一直在尋找代碼,它並不是很明顯,我遇到了什麼問題。當你說你的輸出「全搞砸了」是什麼意思?你的輸出是什麼,你期待它是什麼,還有其他相關的代碼嗎? – Kiril