如何使用Task.run执行后台工作程序的Do_Work()函数 [英] How to use Task.run to perform the function of Do_Work() of a background worker

查看:287
本文介绍了如何使用Task.run执行后台工作程序的Do_Work()函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在存储在路径列表中的特定路径中并行移动4个对象,当每个对象完成一个路径(特定坐标)时,它就会切换到另一个!

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!.

我使用4个后台工作人员在后台执行此类工作,在每个呼叫中​​,每个后台工作人员都应尝试从文本文件中提取6条路径(染色体),并将每条路径存储在不同的6个列表中,并且每个列表都包含坐标每条路径.然后将坐标转换为2D点以执行投影,并在特定深度执行每个路径,因为使用投影技术将这些对象移动到不同层上的路径即每个对象(工人)将在不同层上移动.

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.

下面是一个Do_Work()方法的示例:

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);

我在一个循环了250次的循环中声明了它们,并在每次循环中通过调用包含以下几行的另一种方法来调用它们:

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

问题:

循环与Do_Work()方法之间没有同步,即循环在4个后台工作程序完全完成其工作之前开始新的迭代,其中每个迭代都有一个包含6个不同路径(染色体)的列表,每个后台工作程序应该在使用新列表的下一次迭代之前尝试使用它们.在进行下一次迭代之前,我需要完全停止工作.我在循环外放了一个消息框,即使所有工作人员都停止了,循环结束后我也没有看到它.

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.

我的问题是:

我在使用后台工作程序时遇到了一些问题,所以我想知道是否可以使用Task类,如果可以,那么..那么如何使用Task.runDo_Work()方法内部执行相同的工作?

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 ?

推荐答案

主要概念是:

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);
    }
}

但是,我有一个假设:如果您需要访问UI线程,则应该重写"DoWork"方法.您应该在尝试更改UI的所有部分中添加调度程序.

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.

这篇关于如何使用Task.run执行后台工作程序的Do_Work()函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆