我正在编写一个数独求解器应用程序。在某些情况下,求解器的计算时间可能超过3秒,这需要一个进度条。
所以我的代码:
private void solveButton_Click(object sender, RoutedEventArgs e)
{
progressBar1.Visibility = Visibility.Visible;
progressBar1.IsIndeterminate = true;
mySolver.Solve(initialValue)
progressBar1.Visilibity=Visilibity.collapsed;
progressBar1.IsIndeterminate = false;
}
这里的代码是我实际代码的精简版本。此代码不起作用,因为进度条根本不显示。在我看来,UI只在事件执行完毕后才更新。如果我在解算器步骤之后没有隐藏进度条,则在数独解决之后会出现progressBar。用thread.sleep(1000)替换解算器也会导致相同的UI更新。
感谢您的帮助。
答案 0 :(得分:4)
问题是你的UI线程之间没有空闲来显示进度条 您需要使用后台工作程序来解决问题,并且在主UI线程中您应该显示进度条
private void solveButton_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += new DoWorkEventHandler(DoWork);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
bg.RunWorkerAsync();
progressBar1.Visibility = Visibility.Visible;
progressBar1.IsIndeterminate = true;
}
void DoWork(Object sender, DoWorkEventArgs args)
{
mySolver.Solve(initialValue)
}
void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs args)
{
// this method will be called once background worker has completed it's task
progressBar1.Visilibity=Visilibity.collapsed;
progressBar1.IsIndeterminate = false
}
答案 1 :(得分:4)
您应该在单独的线程上启动解算器。这样,即使在求解过程中,用户界面线程也可以继续处理用户界面对象,这样就可以在屏幕上绘制并更新进度条。
答案 2 :(得分:2)
从技术上讲,代码工作正常,你只是写错了代码。
您的求解程序正在UI线程上运行,因此在您再次隐藏它之前,它永远无法绘制进度条。您需要生成一个线程(或使用后台工作程序)来释放UI线程,以便它可以绘制您的进度条。
答案 3 :(得分:1)
我对WP7知之甚少,但如果你有一个长时间运行的函数需要winforms,它需要在与UI不同的线程上运行。
WP7上有BackgroundWorker可用吗?您可以更新ProgressChanged
活动的栏,并更改RunWorkerCompleted
活动的可行性
private void solveButton_Click(object sender, RoutedEventArgs e)
{
progressBar1.Visibility = Visibility.Visible;
progressBar1.IsIndeterminate = true;
solveButton.Enabled = false; //I reccomend this so the button can't be pressed twice.
BackgroundWoker bw = new BackgroundWorker();
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerAsync()
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
mySolver.Solve(initialValue, e)
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Error != null)
{
//Handle any exceptions that happened in the background worker.
}
progressBar1.Visilibity=Visilibity.collapsed;
progressBar1.IsIndeterminate = false;
solveButton.Enabled = true;
((IDisposable)sender).Dispose();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
//inside mySolver
void Solve(somthing initialValue, DoWorkEventArgs e)
{
//Your solver work
e.ReportProgress(progress); //a int from 0-100
//more solver work
}
答案 4 :(得分:0)
如果您仍想在UI线程上运行它(我不推荐!!),您可以使用昨天发布的WP7工具包中的进度条。它包含一个在您的UI线程被阻止时可以使用的进度条。