尝试更新更新的UI元素,DoWork()通过可视化进度条和提供当前值的文本框迭代DataTable中的每一行。迭代发生在后台工作程序中并按预期工作,进度条的PerformStep()也是如此。但是,TextBox的文本不会更改。
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
table = SegmentationLibrary.Core.Utils.GetTableFromQuery(query);
backgroundWorker1.ReportProgress(table.Rows.Count, "Max");
int status = 0;
backgroundWorker1.ReportProgress(status);
table.Columns.Add("seg_rates_id", typeof(Int32));
foreach (DataRow row in table.Rows)
{
row["seg_rates_id"] = 0;
status++;
backgroundWorker1.ReportProgress(status);
Application.DoEvents();
}
}
进度:
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.UserState != null && e.UserState.ToString() == "Max") {
progressBar.progressBar1.Maximum = e.ProgressPercentage;
}
else if (e.ProgressPercentage == 0)
{
progressBar.progressBar1.Minimum = 0;
progressBar.progressBar1.Style = ProgressBarStyle.Continuous;
progressBar.progressBar1.Value = 1;
progressBar.progressBar1.Step = 1;
progressBar.tbProgress.Text = "Setting initial rate types";
}
else
{
progressBar.progressBar1.PerformStep();
progressBar.tbProgress.Text = "Current at row " + progressBar.progressBar1.Value + " of " + progressBar.progressBar1.Maximum + ", " + progressBar.GetProgressBarPercent().ToString() + "%.";
}
}
呼叫者:
public void GetFinacData(int year, int month)
{
if (!backgroundWorker1.IsBusy)
{
Application.EnableVisualStyles();
currentMonth = month;
currentYear = year;
query = "SELECT * FROM FINAC_ACTUAL_DATA WHERE fiscal_year = " +
currentYear + " AND fiscal_month = " + currentMonth + ";";
progressBar.Show();
progressBar.progressBarStyle = ProgressBarStyle.Marquee;
progressBar.tbProgress.Text = "Downloading PSGL Extract from database";
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
backgroundWorker1.RunWorkerAsync();
// required for ProgressBar to update?
while (backgroundWorker1.IsBusy)
Application.DoEvents();
workerCompleted.WaitOne();
progressBar.Hide();
}
else
{
MessageBox.Show("Segmentation already in progress.","Error",MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
发生了什么:
我尝试了一些不同的东西,但没有一个能奏效。在ProgressChanged末尾添加另一个DoEvents()会导致堆栈溢出。有什么想法吗?
答案 0 :(得分:1)
你可以用你在这段代码中改变代码来包装你
this.Invoke(new Action(() => { /* ui changing code */ }));
答案 1 :(得分:0)
您可以从后台工作进行更新,而不是从主线程进行更新。此时,您的主线程仍在运行,并且不会处理您的更新。
除去
// required for ProgressBar to update?
while (backgroundWorker1.IsBusy)
Application.DoEvents();
workerCompleted.WaitOne();
progressBar.Hide();
然后移动:
progressBar.Hide();
到你的后台工作人员的结尾。并从代码中删除所有DoEvent。不需要进行更新。