簡體   English   中英

如何使用Task.run執行后台工作程序的Do_Work()功能

[英]How to use Task.run to perform the function of Do_Work() of a background worker

我在存儲在路徑列表中的特定路徑中並行移動4個對象,當每個對象完成一個路徑(特定坐標)時,它將切換到另一個!

我使用4個后台工作人員在后台執行此類工作,並且在每個調用中,每個后台工作人員都應嘗試從文本文件中提取6條路徑(染色體),並將每條路徑存儲在不同的6個列表中,並且每個列表包含每個路徑的坐標。 然后將坐標轉換為2D點以執行投影,並在特定深度執行每個路徑,作為使用投影技術將這些對象移動到不同層上的路徑,即,每個對象(工人)將在不同層上移動。

每個工作人員應使用一條路徑(染色體)向前和向后移動對象,然后切換到下一條路徑,並且在切換到下一條路徑之前,它應該完全完成第一次嘗試(路徑),以便計算所花費的時間和其他因素,例如“健身”功能。

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

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

    }

我宣布每個背景工作者是這樣的:

    auv0Genetic = new BackgroundWorker();

                    auv0Genetic.WorkerSupportsCancellation = true;

                    auv0Genetic.DoWork += new DoWorkEventHandler(auv0Genetic_DoWork);

                    auv0Genetic.RunWorkerCompleted += new 

RunWorkerCompletedEventHandler(auv0Genetic_RunWorkerCompleted);

我在一個循環了250次的循環中聲明了它們,並在每次循環中通過調用包含以下行的另一個方法來調用它們:

auv0Genetic.RunWorkerAsync(geneticIteration); // start AUV # 1

問題 :

循環與Do_Work()方法之間沒有同步,即循環在4個后台工作程序完全完成其工作之前開始新的迭代,其中每個迭代都有一個包含6個不同路徑(染色體)的列表,每個后台工作人員都應嘗試它們在使用新列表進行下一次迭代之前。 在進行下一次迭代之前,我需要完全停止工作。 我在循環外放置了一個消息框,即使所有工作人員都停止了,循環結束后我也沒有看到它。

我的問題是:

我在使用后台工作程序時遇到了一些問題,所以我想知道是否可以使用Task類,如果可以,那么如何使用Task.runDo_Work()方法中執行相同的工作?

主要概念是:

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的所有部分中添加調度程序。

我的假設能夠給出答案:

  • 聽起來您對使用任務很感興趣,這將使用具有關聯任務的對象,是的,它比處理后台工作人員要流暢得多。
  • 我將假設您了解您的業務邏輯,而我則不需要。

  • 我將重點介紹一種以統一方式處理數據的方法,並帶有增加容量的選項。

  • 我當然願意修改和闡明不清楚的地方。

  • 應該將其視為Psuedo代碼,我沒有進行編譯,並且由於缺少想法而無法進行編譯。 可能需要進行一些修改以解決小問題,因為我在這里追求大圖景而不是細節。

編碼

包括

包括您將需要:

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;

處理循環

這是可以從單個后台工作人員調用的主循環:

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


}

工人階級

注意:您可能需要考慮很多其他任務狀態,例如IsFaulted等。我想保持簡潔,因此我沒有涉及這些情況,但是您可能不得不考慮它們。

這是將負責大部分工作的工人階級:

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

        }

    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM