【发布时间】:2016-10-05 10:29:07
【问题描述】:
所以我目前正在使用 Windows 窗体和 C# 为游戏编写关卡生成器。我有一个 BackgroundWorker 正在执行所有生成操作,这样 UI 线程就不会被阻塞,并且可以根据需要自行更新。我目前使用 BackgroundWorkers ReportProgress() 函数更新进度条,但 id 也希望能够根据生成器所在的位置更新标签,即“初始化级别 2”、“将对象放置在级别 3”等。
我尝试从 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 窗体标签从生成器中更新?
【问题讨论】:
-
您可以使用 ReportProgress 方法的第二个参数 userState 将数据发送到 backgroundWorker_ProgressChanged 方法。然后你可以从事件参数 e.UserState 中得到它。