Home:ALL Converter>How to set label text in Windows Forms from a BackgroundWorker

How to set label text in Windows Forms from a BackgroundWorker

Ask Time:2016-10-05T18:29:07         Author:Conor Watson

Json Formatter

So I am currently writing a Level Generator for a game using Windows Forms and C#. I have a BackgroundWorker that is doing all of the Generation so that the UI thread is not held up and can update itself as necessary. I currently update a progress bar using the BackgroundWorkers ReportProgress() function, but id also like to be able to update a label based on where the generator is at, i.e "Initialising Level 2", "Placing objects in Level 3" etc.

I tried to call the updateProgress() function from the backgroundWorker (I pass it and the form into the Generator constructor) to do that but it doesn't work because I get a Cross-Threading error.

 public partial class mainForm : Form
    {
        LevelGen Generator;
        List<Level> levelSet;

        public mainForm()
        {
            InitializeComponent();;
            Generator = new LevelGen(this, backgroundWorker, timer);
        }



        private void button_GenLevels_Click(object sender, EventArgs e)
        {             
            if (!backgroundWorker.IsBusy)
            {
                progressBar.Value = 0;

                backgroundWorker.RunWorkerAsync();
            }
            else
            {
                backgroundWorker.CancelAsync();
            }
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            levelSet = Generator.startGeneration();
        }

        public void updateProgress(int percentage, string currentWork)
        {
            label_processInfo.Text = percentage + " - " + currentWork;
            backgroundWorker.ReportProgress(percentage);
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ListLevels(levelSet);
        }

    }

And it would be getting called like this inside the Generator:

public Level generateLevel(int noOfLevels, int noOfBoxes, int roomHeight, int roomWidth, int difficulty, int levelNum, int totalLevels)
        {
            bool generationSuccessful = false;
            Level newLevel = new Level();
            float percentage;
            int indProcesses = 2;
            int totalProcesses = totalLevels * (indProcesses + 1);

            while (!generationSuccessful)
            {
                newLevel = new Level();

                calculateProperties(ref noOfBoxes, ref difficulty, ref roomHeight, ref roomWidth);

                percentage = (((levelNum * indProcesses)) * 100) / totalProcesses;
                form.updateProgress((int)percentage, "Init Level " + levelNum);

                initLevel(ref newLevel, roomHeight, roomWidth);

                percentage = (((levelNum * indProcesses) + 1) * 100) / totalProcesses;
                form.updateProgress((int)percentage, "Placing Patterns in Level " + levelNum);

                placePatterns(ref newLevel, roomHeight, roomWidth);

                generationSuccessful = true;
            }

            percentage = (((levelNum * indProcesses) + 2) * 100) / totalProcesses;
            form.updateProgress((int)percentage, "Level " + levelNum + " Generated");

            return newLevel;
        }

How should I tell the Windows Form Label to update from within the Generator?

Author:Conor Watson,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/39871531/how-to-set-label-text-in-windows-forms-from-a-backgroundworker
Lidaranis :

Based on the comment i just leaved.\n\n public void updateProgress(int percentage, string currentWork)\n {\n label_processInfo.Text = percentage + \" - \" + currentWork;\n backgroundWorker.ReportProgress(percentage,\"New Label Value\");\n }\n private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)\n {\n progressBar.Value = e.ProgressPercentage;\n string newLabelValue = (String)e.UserState;\n }\n\n\nAlso the user state is an object, so you can send anything you want.",
2016-10-05T10:40:29
yy