所以我目前正在为使用Windows Forms和C#的游戏编写一个Level Generator。我有一个BackgroundWorker
正在执行所有生成,因此UI线程不会被阻止,并且可以根据需要自行更新。我目前使用BackgroundWorkers ReportProgress()
函数更新进度条,但id也希望能够根据生成器所处的位置更新标签,即"初始化级别2",&#34 ;将对象放置在3级和#34;等。
我尝试从backgroundWorker中调用updateProgress()
函数(我将它传递给Generator构造函数),但是它没有工作,因为我遇到了交叉线程错误。
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);
}
}
它会在发电机内被调用:
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;
}
如何告知Windows表单标签在Generator中更新?
答案 0 :(得分:1)
基于我刚刚发表的评论。
public void updateProgress(int percentage, string currentWork)
{
label_processInfo.Text = percentage + " - " + currentWork;
backgroundWorker.ReportProgress(percentage,"New Label Value");
}
private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
string newLabelValue = (String)e.UserState;
}
用户状态也是一个对象,因此您可以发送任何内容。
答案 1 :(得分:0)
您还可以使用委托并检查.InvokeRequired是否以线程安全的方式更新UI元素:
delegate void SetTextCallback(string text);
private void SetDebugText(string RxString)
{
if (this.btnDebug.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetDebugText);
this.Invoke(d, new object[] { RxString });
}
else
{
this.btnDebug.Text = RxString;
}
}