C# WPF-ProgressBar仅在流程完成之前更新
我正在尝试使用ProgressBar,这对我来说是新的(只有异步可能?) 我跟着这条路走,没有遇到任何问题。我只是把代码再次放在这里C# WPF-ProgressBar仅在流程完成之前更新,c#,wpf,progress-bar,C#,Wpf,Progress Bar,我正在尝试使用ProgressBar,这对我来说是新的(只有异步可能?) 我跟着这条路走,没有遇到任何问题。我只是把代码再次放在这里 public partial class ProgressBarTaskOnWorkerThread : Window { public ProgressBarTaskOnWorkerThread() { InitializeComponent(); } private void Window_ContentRen
public partial class ProgressBarTaskOnWorkerThread : Window
{
public ProgressBarTaskOnWorkerThread()
{
InitializeComponent();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += worker_DoWork;
worker.ProgressChanged += worker_ProgressChanged;
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
for(int i = 0; i < 100; i++)
{
(sender as BackgroundWorker).ReportProgress(i);
Thread.Sleep(100);
}
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pbStatus.Value = e.ProgressPercentage;
}
}
在我的代码中,我导入了一个文件列表,因此我将此.ValueProgress设置为0,然后每次导入文件时,我都执行此操作。ValueProgress=100*NumberImportedFiles/TotalFiles
在调试中,我还注意到我的worker\u ProgressChanged
函数在导入时不工作(但是worker\u DoWork
工作正常)。然后,只有在导入所有文件时,才会多次启动worker\u ProgressChanged
(似乎只是一次触发所有已完成的更改)
编辑:刚刚做了另一个“愚蠢”的测试:
我保留了原始代码,添加了一个条件,因此在编辑ValueProgress后ProgressBar将开始移动:
void worker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 100; i++)
{
if(this.ValueProgress==0)
{
i--;
}
(sender as BackgroundWorker).ReportProgress(i);
Thread.Sleep(100);
}
}
void worker\u DoWork(对象发送方,DoWorkEventArgs e)
{
对于(int i=0;i<100;i++)
{
if(this.ValueProgress==0)
{
我--;
}
(发送方作为后台工作人员)。报告进度(i);
睡眠(100);
}
}
代码也不起作用,我的意思是,函数
worker\u DoWork
工作正常,进程开始后我开始增加,但进程栏没有移动(worker\u ProgressChanged没有启动)。我没有评论的名声,所以我发布了一个答案。如果我的一些假设是错误的,我会提前道歉。您在哪里设置ValueProgress的值?如果您在UI线程上设置ValueProgress的值,而不是使用后台工作,则可能会挂起UI线程
如果是这种情况,则不会显示对进度条的任何更新。尝试在后台工作程序中执行任何更新,以保持UI可以自由更新
以下是有助于解决此问题的教程,您可以尝试在主线程上更新ProgressBar
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Application.Current.Dispatcher.Invoke(() => pbStatus.Value = e.ProgressPercentage);
}
问题是,在另一个线程上更新UI将不起作用。只有主线程可以。在ReportProgress之前打印this.valueProgress的值-它正在更改/增加吗?@pratekshrivastava是的is@PrateekShrivastava谢谢,事实上问题是我不明白BackgroundWorker是如何工作的。在Arc2006回答之后,我可以通过阅读另一个教程来理解它。所以你是对的,我没有在后台工作中保存值进度,你能解释一下如何做到这一点吗?(到目前为止从未使用过异步函数)。刚找到一本关于
BackgroundWorker
的教程,我会先读一读,谢谢,我想我已经理解了你的传统意思,启动后台工作程序时,所有正在更改值的代码都应该放在分配给worker.DoWork的方法中——在本例中为worker\u DoWork。您可以在工作线程之外更改值,但在所有代码完成执行之前,UI不会反映更改。是的,我现在理解阅读教程(仍在上面),老实说,现在我不明白您的意思,但在阅读教程后,我想我会,似乎没有那么困难。如果我理解了教程,所有代码(导入文件)可能不在我的UI中,但在worker\u DoWork
函数中?只能在异步模式下管理ProgesBar?
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Application.Current.Dispatcher.Invoke(() => pbStatus.Value = e.ProgressPercentage);
}