Как запустить тот же фоновый рабочий и остановить его внутри цикла в C#
Я написал следующий код для выполнения генетического алгоритма, который повторяется 10 раз, и каждый раз, когда я вызываю функцию "FitnessFunction", я использую фоновый рабочий для перемещения объекта по топологии, и как только он достигает определенной точки, я отменяю этот фоновый рабочий и возвращаюсь к функции "Genetic_Algorithm"...
К сожалению, я получил следующую ошибку, когда нажал на кнопку" MOVE-AUV-GAAPS", которая вызывает метод "Genetic_Algorithm" :
Cross-thread operation not valid: Control 'topology' accessed from a thread other than the thread it was created on...и указать на:
while(true)который находится в функции "AUVbackGWgenetic_DoWork".
Функция "Genetic_Algorithm" :
<pre> static int geneticIteration; static BackgroundWorker AUVbackGWgenetic; public void Genetic_Algorithm(int[][,] population) { double[,] FitnessValue = new double[6, 2]; // for all five chromosome we store two Values the Fitness Value and the Fitness Ratio int[] RouletteWheel = new int[6]; int round=0; for (int geneticIteration = 0; geneticIteration < 10; geneticIteration++) { round = geneticIteration + 1; writer = new StreamWriter("C:/Users/Welcome/Desktop/listOfChromosomesForAllRounds.txt", true); writer.WriteLine("----------------------------------------------------------------------"); Chromosomes(population,round); // Calculate the fitness Function and the Fitness Ratio FitnessFunction(population); // Fitness Function //RouletteWheel = RouletteWheel_Selection(population,FitnessValue); // Selection //population = CrosssOver(RouletteWheel, population); //Cross Over //population = Mutation(RouletteWheel, population); // Mutation writer.Close(); } //Store best path in the array as a group of XY coordinates //for(int i=0;i<auvChromosomes.Length;i++) //{ // } //completeAUVMovement(int[,]auvPath); }
Функция "FitnessFunction" :
public void FitnessFunction(int[][,] population) { double[,] FitnessValue = new double[6, 2]; // for all five chromosome we store two Values the Fitness Value and the Fitness Ratio AUVbackGWgenetic = new BackgroundWorker(); AUVbackGWgenetic.DoWork += new DoWorkEventHandler (AUVbackGWgenetic_DoWork); AUVbackGWgenetic.RunWorkerAsync(geneticIteration); }
Функция "AUVbackGWgenetic_DoWork" :
private void AUVbackGWgenetic_DoWork(object sender, DoWorkEventArgs e) { Random rnd = new Random(); SoundPlayer player = new SoundPlayer("C:/Users/Welcome/Desktop/project/GAAPS/Sonar_pings.wav"); auv.auvX = rnd.Next(200, 325); auv.auvY = rnd.Next(200, 325); while (true) { Thread.Sleep(300); // assume that it represents the speed of the AUV which is in our case = 3 m/s if (AUVbackGWgenetic.CancellationPending) { e.Cancel = true; return; } if (auv.auvY == 200) { if (auv.queue1.Count != 0) { Thread.Sleep(1000); foreach (Packet packet in auv.queue1) { auv.SendToSink(packet); } auv.queue1.Clear(); topology.CreateGraphics().DrawString("Received Aggrigated Data from AUV # " + auv.auvID, new Font("Times New Roman", 7.0f), Brushes.Red, sink.sinkX - 48, sink.sinkY - 15); // Display the sink name topology.CreateGraphics().DrawLine(dash, auv.auvX, auv.auvY, sink.sinkX + 20, sink.sinkY + 45); player.Play(); Thread.Sleep(3000); player.Stop(); } } if (forward) { auv.auvX += 3; auv.auvY += 3; if (auv.auvY >= 326) { backward = true; forward = false; countNumOfPaths++; } } if (backward) { auv.auvX -= 3; auv.auvY -= 3; if (auv.auvY >= 200) { backward = false; forward = true; countNumOfPaths++; } if (countNumOfPaths >= 2) { AUVbackGWgenetic.CancelAsync(); } } //////////////////////// Draw /////////////////////////// iSetupDisplay = 0; if (iSetupDisplay != -1) { iSetupDisplay += 10; if (iSetupDisplay >= topology.Width) iSetupDisplay = -1; topology.Refresh(); } ///////////////////////////////////////////////////////// } }
Следующая ссылка содержит картинку для моего приложения WF : Здесь
Что я уже пробовал:
Мне нужно запускать фоновый рабочий процесс каждый раз, когда я вызываю функцию "FitnessFunction", которая отвечает за его остановку при определенном условии.
[no name]
"Операция перекрестного потока недопустима" означает именно то, что она говорит. Это можно исправить, не пытаясь получить доступ к элементам управления пользовательского интерфейса из потоков, которые им не владеют, или вызвать вызовы для обновления элементов управления пользовательского интерфейса в потоке пользовательского интерфейса. Небольшое исследование может иметь большое значение для решения ваших собственных проблем.
Member 11247684
как это исправить, не могли бы вы дать ответ?..
Я новичок в Си#
Все Тины в порядке прямо сейчас ожидайте этой проблемы ...
Philippe Mori
Самый простой способ решить проблему-позвонить ReportProgress
с пользовательским объектом и иметь обработчик для этого. Используя отладчик, легко выяснить, где есть кросс-потоковые операции при условии, что вы остановитесь на исключениях. Это решение должно работать нормально при условии, что вам не нужно много общаться с пользовательским интерфейсом (скажем, менее 100 звонков в секунду). Если существует гораздо больше коммуникаций, то вам нужно будет потратить время на изучение многопоточности, чтобы вы могли писать эффективный код.
Philippe Mori
Если вы вручную добавите обработчик в FitnessFunction
, затем вы должны удалить его, когда он больше не нужен, и убедиться, что вы не будете присоединять обработчик несколько раз, если эта функция вызывается более одного раза.
Member 11247684
не могли бы вы дать подробный ответ?.. и используйте мой код в качестве примера