在我的XML編輯器中,我希望能夠使用索引文件一次打開多個文件。顯然,根據文件數量的不同,這可能需要一些時間,我想使用進度條來通知用戶程序仍在加載並執行某些操作。 從我研究的方式來保持UI進度欄更新使用BackgroundWorker。如何讓BackgroundWorker阻止UI線程?
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的法的標籤列表我包裹在Dispathcer.Invoke這一呼籲。在這種形式下,代碼類型做我想要的。它使摺疊的progressBar可見並每隔一段時間更新一次。可悲的是,它不會在每次加載文件後更新百分比。從控制檯中可以看到,ProgressChanged執行滯後於DoWork。根據我的理解,它在循環的每個迭代中都被調用。即使它觸發了,用戶界面並不總是對此作出響應。
所以我的問題是:我仍然阻止UI線程以及我怎麼修復它?
這工作,現在它是如此之快,我幾乎不再需要進度條了......謝謝! – Ultus
不幸的是沒有爲我工作。我正在報告當前循環'i',並在報告事件中將此int設置爲名爲'ProgressValue'的屬性。這個'ProgressValue'作爲值綁定到進度條。我的用戶界面仍然阻塞。 – C4u
@ C4u那麼改變那個怎麼樣? (我看不到你的問題)。在「DoWork」中執行你的工作(所有的值必須是來自你的用戶界面的自治),並且每次你完成一個部分時,通過ReportProgress將它報告給你的用戶界面威脅(在這裏你可以使用UI值(比如'ProgressValue')如果你需要在你的UI中再做一些事情,那麼當你所有的工作完成時調用'RunWorkerCompleted',我希望這會幫助你:-) – WiiMaxx