我正在使用WPF尝试在后台运行一个更新进度条的线程。我不想阻止UI线程,所以我运行以下代码。但是UI仍然被阻止。看起来很简单,我做错了什么?
Dispatcher.BeginInvoke(
(ThreadStart) delegate(){
for(double i = progressBar_ChangeProgress.Minimum;
i < progressBar_ChangeProgress.Maximum;
i++)
{
for (int b = 0; b < 100000000; b++) { }
progressBar_ChangeProgress.Value = i;
}
EnableAllInputControls();
}, DispatcherPriority.Background);
答案 0 :(得分:5)
为什么不在这种情况下利用BackgroundWorker
......
void Go()
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerAsync();
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar_ChangeProgress.Value = e.ProgressPercentage;
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int b = 0; b < 100; b++)
{
Thread.Sleep(100);
worker.ReportProgress(b);
}
}
<强>更新强>
如果您想使用Dispatcher
;将优先级设置为Normal
并在后台线程上执行处理,然后在UI线程上调用方法以提供更新。
void Go()
{
ThreadStart start = delegate()
{
//this is taking place on the background thread
for (int i = 0; i < 100; i++)
{
//this is slowing things down; no real relevance
Thread.Sleep(100);
//this will marshal us back to the UI thread
Dispatcher.Invoke(DispatcherPriority.Normal,
new Action<int>(Update), i
);
}
};
new Thread(start).Start();
}
void Update(int value)
{
//this is taking place on the UI thread
_progressBar.Value = value;
}
答案 1 :(得分:2)
Dispatcher
只是一种在以后的UI线程上运行一些代码的机制。您传入的优先级控制 它将被执行,而不是任何类型的线程优先级。在这种情况下,您的委托的内容将在UI线程上运行。使用Aaron提到的BackgroundWorker
肯定会对此有所帮助。
另外我可能会指出,通常一个进度条显示任务完成的接近程度。如果您不知道要采取多长时间或无法测量进度,可以使用不确定进度条。如果您有一些有意义的信息,请仅更新该值。 (尽管你可能刚刚提供了这个用于演示目的)
答案 2 :(得分:0)
BeginInvoke 内的所有内容都在UI线程上运行,因此会阻止。
您需要做的是在线程中运行任何时间密集的代码,然后只更新Invoke中的UI。
你想要更像这样的东西:
for (double i = progressBar_ChangeProgress.Minimum;
i < progressBar_ChangeProgress.Maximum;
i++)
{
for (int b = 0; b < 100000000; b++) { }
Dispatcher.Invoke((ThreadStart) delegate(){
progressBar_ChangeProgress.Value = i;
});
}