I move 4 objects in parallel in a specific paths stored in a list of paths, when each of them complete one path(specific coordinates) it switches to another!.
I used 4 background workers to perform such a job in background and in each call each background worker should try 6 paths (chromosomes) extracted from an a text file and each path stored in different 6 lists and each list contains the coordinates for each path. The coordinates then converted to 2D points to perform projection and each path at a specific depth as the paths to move these objects on different layers using a projection technique ie ach object (worker) will be moved at different layer.
Each worker should move the object forward and backward using one path (chromosome) then switches to the next and it should finish the first attempt (path) completely before switch to next in order to calculate the time consumed and other factors such as "Fitness" function.
The following is an example on one the Do_Work() methods:
private void auv0Genetic_DoWork(object sender, DoWorkEventArgs e)
{
List<PointF> genetic2DLayerPath1 = new List<PointF>(); // from chromosome 1
List<PointF> genetic2DLayerPath2 = new List<PointF>(); // from chromosome 2
List<PointF> genetic2DLayerPath3 = new List<PointF>(); // from chromosome 3
List<PointF> genetic2DLayerPath4 = new List<PointF>(); // from chromosome 4
List<PointF> genetic2DLayerPath5 = new List<PointF>(); // from chromosome 5
List<PointF> genetic2DLayerPath6 = new List<PointF>(); // from chromosome 6
countNumOfPaths_auv_1 = 0;
float[] xPoints = new float[1];
float[] yPoints = new float[1];
foreach (int[,] arr in pathChromosom1)
{
Point3D pointIn3D = new Point3D(cellsCenters[0, arr[0, 0]], cellsCenters[1, arr[1, 0]], 700);
PointF pointIn2D = Project(pointIn3D); // convert to 2D
genetic2DLayerPath1.Add(pointIn2D);
}
foreach (int[,] arr in pathChromosom2)
{
Point3D pointIn3D = new Point3D(cellsCenters[0, arr[0, 0]], cellsCenters[1, arr[1, 0]], 700);
PointF pointIn2D = Project(pointIn3D); // convert to 2D
genetic2DLayerPath2.Add(pointIn2D);
}
foreach (int[,] arr in pathChromosom3)
{
Point3D pointIn3D = new Point3D(cellsCenters[0, arr[0, 0]], cellsCenters[1, arr[1, 0]], 700);
PointF pointIn2D = Project(pointIn3D); // convert to 2D
genetic2DLayerPath3.Add(pointIn2D);
}
foreach (int[,] arr in pathChromosom4)
{
Point3D pointIn3D = new Point3D(cellsCenters[0, arr[0, 0]], cellsCenters[1, arr[1, 0]], 700);
PointF pointIn2D = Project(pointIn3D); // convert to 2D
genetic2DLayerPath4.Add(pointIn2D);
}
foreach (int[,] arr in pathChromosom5)
{
Point3D pointIn3D = new Point3D(cellsCenters[0, arr[0, 0]], cellsCenters[1, arr[1, 0]], 700);
PointF pointIn2D = Project(pointIn3D); // convert to 2D
genetic2DLayerPath5.Add(pointIn2D);
}
foreach (int[,] arr in pathChromosom6)
{
Point3D pointIn3D = new Point3D(cellsCenters[0, arr[0, 0]], cellsCenters[1, arr[1, 0]], 700);
PointF pointIn2D = Project(pointIn3D); // convert to 2D
genetic2DLayerPath6.Add(pointIn2D);
}
int counter = 0;
for (int i = 0; i < 6; i++)
{
if (i == 0) // first chromosome
{
xPoints = new float[genetic2DLayerPath1.Count()];
yPoints = new float[genetic2DLayerPath1.Count()];
auv[0].auvDepth = 700;
foreach(PointF p in genetic2DLayerPath1)
{
xPoints[counter] = p.X;
yPoints[counter] = p.Y;
counter++;
}
counter = 0;
}
if (i == 1) // second chromosome
{
xPoints = new float[genetic2DLayerPath2.Count()];
yPoints = new float[genetic2DLayerPath2.Count()];
auv[0].auvDepth = 700;
foreach (PointF p in genetic2DLayerPath2)
{
xPoints[counter] = p.X;
yPoints[counter] = p.Y;
counter++;
}
counter = 0;
}
if (i == 2) // third chromosome
{
xPoints = new float[genetic2DLayerPath3.Count()];
yPoints = new float[genetic2DLayerPath3.Count()];
auv[0].auvDepth = 700;
foreach (PointF p in genetic2DLayerPath3)
{
xPoints[counter] = p.X;
yPoints[counter] = p.Y;
counter++;
}
counter = 0;
}
if (i == 3) // fourth chromosome
{
xPoints = new float[genetic2DLayerPath4.Count()];
yPoints = new float[genetic2DLayerPath4.Count()];
auv[0].auvDepth = 700;
foreach (PointF p in genetic2DLayerPath4)
{
xPoints[counter] = p.X;
yPoints[counter] = p.Y;
counter++;
}
counter = 0;
}
if (i == 4) // fifth chromosome
{
xPoints = new float[genetic2DLayerPath5.Count()];
yPoints = new float[genetic2DLayerPath5.Count()];
auv[0].auvDepth = 700;
foreach (PointF p in genetic2DLayerPath5)
{
xPoints[counter] = p.X;
yPoints[counter] = p.Y;
counter++;
}
counter = 0;
}
if (i == 5) // sixth chromosome
{
xPoints = new float[genetic2DLayerPath6.Count()];
yPoints = new float[genetic2DLayerPath6.Count()];
auv[0].auvDepth = 700;
foreach (PointF p in genetic2DLayerPath6)
{
xPoints[counter] = p.X;
yPoints[counter] = p.Y;
counter++;
}
counter = 0;
}
counter = 0;
while (countNumOfPaths_auv_1 != 2)
{
Thread.Sleep(900); // assume that it represents the speed of the AUV which is in our case = 3 m/s as each meter equal to 300 seconds in thread.sleep()
if (auv0Genetic.CancellationPending)
{
e.Cancel = true;
return;
}
if (forward)
{
if (counter == xPoints.Length - 1)
{
backward = true;
forward = false;
countNumOfPaths_auv_1++;
}
else
{
auv[0].auvX = xPoints[counter];
auv[0].auvY = yPoints[counter];
counter++;
}
}
if (backward)
{
if (counter == 0)
{
backward = false;
forward = true;
countNumOfPaths_auv_1++;
}
else
{
auv[0].auvX = xPoints[counter];
auv[0].auvY = yPoints[counter];
counter--;
}
}
//////////////////////// Draw ///////////////////////////
iSetupDisplay = 0;
if (iSetupDisplay != -1)
{
iSetupDisplay += 10;
if (iSetupDisplay >= topology.Width)
iSetupDisplay = -1;
topology.Refresh();
}
/////////////////////////////////////////////////////////
}
}
}
I declared each background worker like this:
auv0Genetic = new BackgroundWorker();
auv0Genetic.WorkerSupportsCancellation = true;
auv0Genetic.DoWork += new DoWorkEventHandler(auv0Genetic_DoWork);
auv0Genetic.RunWorkerCompleted += new
RunWorkerCompletedEventHandler(auv0Genetic_RunWorkerCompleted);
I declared them in a loop that loops 250 times and call them inside this loop each time by calling another method that contains the following lines:
auv0Genetic.RunWorkerAsync(geneticIteration); // start AUV # 1
Problems :
There is no synchronization between the loop and the Do_Work()
method ie the loop starts new iteration before the 4 backgrounds worker finishes their work completely where for each iteration there is a list contains 6 different paths (chromosomes) and each background worker should tries them before the next iteration with the new list. I need to stop the workers completely before going to the next iteration. I put a message box outside the loop and I do not get it appeared after the completion of the loop even after all the workers stop.
My Question Is:
I faced some problems with using background workers so I wondered if it is possible to use Task class instead, if so .. then how to use Task.run
to perform the same job inside Do_Work()
methods ?
The main concept is:
public async Task WorkerStartedMethod()
{
for(int i = 0; i<=250; i++)
{
List<Task> tasks = new List<Task>();
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
tasks.add(Task.Run(auv0Genetic_DoWork));
await Task.WhenAll(tasks);
}
}
However I have an assumption that "DoWork" method should be rewritten in case you need access to the UI thread. You should add dispatchers in all parts where you try change something on the UI.
I am going to assume that you understand your business logic and there is no need for me to.
I will focus on a way to process data in a uniform way with options to increase capacity.
Of course I am willing to amend and illuminate unclear areas.
This should be considered Psuedo Code, I did not compile this and with the missing ideas it would not compile. Some edits to fix small things may be needed as I was going for the big picture idea here not the details.
INCLUDES
The Includes you will need:
using System;
using System.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Diagnostics;
PROCESSING LOOP
This is the main loop you could call this from a single background worker:
public void BeginProcess()
{
//This is the limitation on threads/cpu usage
var maxWorkers = 4;
//You could tackle how to go through the loop many ways this was how I was doing it for a simple file transfer program so I didn't change the paradigm
var currentWorker = 0;
//This is the Worker List that will hold and then run our chromosome business logic
var ChromosomeWorkers = new List<ChromWorker>();
//I am not sure based on the code how you are running through this, but here is a population example
foreach (var chromTemplate in ChromosomeTemplates)
{
var cw = new ChromWorker(/*pass in appropriate arrays etc*/);
ChromosomeWorkers.Add(cw);
//If the count of Running workers is less than Max Workers and we are not at the end of the list Continue starting them
if (ChromosomeWorkers.Count(x => x.Running) < maxWorkers && currentWorker < ChromosomeWorkers.Count)
{
ChromosomeWorkers[currentWorker].Start();
currentWorker++;
}
}
//Transition from Creation to Pure Processing
do
{
if (ChromosomeWorkers.Count(x => x.Running) < maxWorkers && currentWorker < ChromosomeWorkers.Count)
{
FilesToBeTransferred[currentWorker].Start();
currentWorker++;
}
else
{
//If the workers are maxed then sleep for a bit on this thread
Thread.Sleep(150);
}
}
while (currentWorker < ChromosomeWorkers.Count);
}
WORKER CLASS
NOTE: There are a lot of other Task states you might have to account for like IsFaulted, etc. I wanted to keep this concise so I did not go into those cases but you might have to account for them.
This is the worker class which will do most of the footwork:
public class ChromWorker
{
private Task _t;
bool isConsumed = false;
pathChromosom1 [,];
string _Key = string.Empty;
List<Tag> _Tags = new List<Tag>();
public ChromWorker(/*Data that might be useful in your worker*/)
{
pathChromosom1 = inChromosomeArrays;
}
public bool Running
{
get
{
if (_t == null || _t.IsCompleted ) return false;
return true;
}
}
public bool Done
{
get
{
return _t != null && _t.IsCompleted;
}
}
public bool Ready
{
get { return _t == null; }
}
public void Start()
{
_t = new Task(_Run);
_t.Start();
}
private void _Run()
{
double tries = 0;
bool Handled = false;
while (!Handled && tries < Math.Pow(10, 6))
{
//Increase our giveup loop
tries++;
try
{
/* your Business logic */
Handled = true;
}
catch (Exception e)
{
Console.WriteLine("Exception: {0} StackTrace: {1}", e.Message, e.StackTrace);
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.