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?
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