Cal*_*all 8 c# wpf ui-thread progress-bar
我有一个ProgressBarWindow,它有一个进度条和一个取消按钮,我用它来报告文件I/O的进度.但是,尽管在后台工作中完成了所有工作,但ProgressBarWindow的UI线程和我的主窗口都会挂起.进度条呈现,就像我的主窗口一样,但是在后台工作人员执行其操作时不会更新.在主窗口的构造函数的最后调用以下代码:
iCountLogLinesProgressBar = new ProgressBarWindow();
iCountLogLinesProgressBar.cancelButton.Click += EventCountLogLinesProgressBarCancelButtonClicked;
iCountLogLinesProgressBar.Show();
iCountLogRecords = new BackgroundWorker();
iCountLogRecords.DoWork += EventCountLogLinesDoWork;
iCountLogRecords.ProgressChanged += EventCountLogLinesProgressChanged;
iCountLogRecords.RunWorkerCompleted += EventCountLogLinesRunWorkerCompleted;
iCountLogRecords.WorkerReportsProgress = true;
iCountLogRecords.WorkerSupportsCancellation = true;
iCountLogRecords.RunWorkerAsync(new BinaryReader(File.Open(iMainLogFilename, FileMode.Open, FileAccess.Read)));
Run Code Online (Sandbox Code Playgroud)
EventCountLogLinesProgressChanged()看起来像这样:
private void EventCountLogLinesProgressChanged(object sender, ProgressChangedEventArgs e)
{
iCountLogLinesProgressBar.Value = e.ProgressPercentage;
}
Run Code Online (Sandbox Code Playgroud)
这是ProgressBarWindow的缩短版本(其余只是几个setter):
public partial class ProgressBarWindow : Window
{
public ProgressBarWindow()
{
InitializeComponent();
this.progressBar.Value = this.progressBar.Minimum = 0;
this.progressBar.Maximum = 100;
}
public double Value
{
get
{
return progressBar.Value;
}
set
{
this.progressBar.Value = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试在dispatcher.invoke委托中包装值setter行但是这给了我一个堆栈溢出(我不应该有一个dispatcher.invoke行,因为backgroundworker在UI Thread中调用ProgressChanged,对吧?).我已经检查了msdn并用谷歌搜索了但我似乎无法找到其他任何有这个问题的人.
编辑道歉,我没有意识到我的简化代码阻止了UI线程,尽管使用了后台工作,但我得到完全相同的行为,所以我错误地认为它们是等效的.我应该提到我正在使用背景工作者:P
Jon*_*eet 15
您正在阻止UI线程,因此在循环完成之前它不会重新呈现UI.
将后台处理移动到单独的线程中,并使用适当的Dispatcher
调用(或BackgroundWorker
)将UI更新调用封送回UI线程.
如果您的进度条实际上只是一个计时器,您可以使用其中一个Timer
类来更新它.
编辑:好的,现在你已经改变了代码,它看起来对我好.它应该是线程安全的,因为您只是在UI线程上更改UI.您的后台工作人员是否定期报告进度?