在我的XML编辑器中,我希望能够使用索引文件一次打开多个文件。显然,根据文件的数量,这可能需要一些时间,我想使用进度条通知用户程序仍在加载并执行某些操作。 根据我的研究,保持UI进度条更新的方法是使用BackgroundWorker。
public MainWindow()
{
InitializeComponent();
tabList = new ObservableCollection<FileTab>();
tabControl.ItemsSource = tabList;
backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged;
backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted;
backgroundWorker.WorkerReportsProgress = true;
}
(...)
private void OpenProjectButtonClick(object sender, RoutedEventArgs e)
{
openingProgressBar.Value = 0;
openingProgressBar.Visibility = System.Windows.Visibility.Visible;
backgroundWorker.RunWorkerAsync();
}
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
int i = 0;
foreach (IndexFile file in indexManager.fileList)
{
this.Dispatcher.Invoke((Action)(() =>
{
tabList.Add(new FileTab(file.filePath));
}));
i++;
Console.WriteLine("-(DoWork)->" + i);
double percentage = (Convert.ToDouble(i) / Convert.ToDouble(indexManager.fileList.Count)) * 100;
Console.WriteLine("-(DoWork.percentage)-> "+ percentage);
backgroundWorker.ReportProgress((int)percentage);
}
}
void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
openingProgressBar.Value = e.ProgressPercentage;
Console.WriteLine("-(ProgressChanged)->" + openingProgressBar.Value);
}
void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
openingProgressBar.Visibility = System.Windows.Visibility.Collapsed;
backgroundWorker.Dispose();
Console.WriteLine("-(RunWorkerComplete)-> Done");
}
由于我正在访问DoWork-Method中的tablist,因此我将该调用包装在Dispathcer.Invoke中。在这种形式的代码类型做我想要的。它使折叠的progressBar可见,并且每隔一段时间更新一次。可悲的是,它并没有在每个文件加载后更新百分比。从我在控制台中看到的情况来看,ProgressChanged执行落后于DoWork。根据我的理解,它在循环的每次迭代中都被调用。即使它触发了UI,也不会总是回应它。
所以我的问题是:我是否仍以某种方式阻止UI线程,我该如何解决?
答案 0 :(得分:0)
尝试将报告进度操作移动到调度程序的操作中:
foreach (IndexFile file in indexManager.fileList)
{
this.Dispatcher.Invoke((Action)(() =>
{
tabList.Add(new FileTab(file.filePath));
Console.WriteLine("-(DoWork)->" + i);
double percentage = (Convert.ToDouble(i) / Convert.ToDouble(indexManager.fileList.Count)) * 100;
Console.WriteLine("-(DoWork.percentage)-> "+ percentage);
backgroundWorker.ReportProgress((int)percentage);
}));
i++;
}
调度员可能在另一个线程中运行......