Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
178 views
in Technique[技术] by (71.8m points)

c# - How to use Task.run to perform the function of Do_Work() of a background worker

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 i.e. 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 i.e. 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 ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...