在执行某些任务时,不会更新BackgroundWorker的进度条。我想要访问的是进度条在遍历DirectoryInfo中的每个文件时移动。假设我们有20个文件" .sql"第一个文件完成时应该是5%,10%等。 这是我的代码。
private void CSV_Click(object sender, RoutedEventArgs e)
{
try
{
btnExtract.IsEnabled = false;
workerextract.RunWorkerAsync();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
private void workerextract_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
try
{
this.Dispatcher.Invoke(() =>
{
DirectoryInfo di = new DirectoryInfo(txtQueryfolder.Text);
files = di.GetFiles("*.sql").Count();
currentfile = 0;
foreach (FileInfo fi in di.GetFiles("*.sql"))
{
// Open the text file using a stream reader.
using (StreamReader sr = new StreamReader(fi.FullName))
{
// Read the stream to a string, and write the string to the console.
string line = sr.ReadToEnd();
//System.Windows.MessageBox.Show(line);
ExtractToCSV(line, System.IO.Path.GetFileNameWithoutExtension(fi.Name));
currentfile++;
}
int percentage = (currentfile + 1) * 100 / files;
workerextract.ReportProgress(percentage);
}
});
}
catch(Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
private void workerextract_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
progressBarExtract.Value = e.ProgressPercentage;
}
private void workerextract_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
btnExtract.IsEnabled = true;
System.Windows.MessageBox.Show("CSV Data extraction finished!");
}
我找到了
100%时,private void workerextract_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
在结束时被调用一次。 另外,
private void workerextract_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
从未打电话,因为我最后没有看到消息框。
所以,我觉得我在这里做错了,你能指导我吗?
答案 0 :(得分:0)
在this.Dispatcher.Invoke
的{{1}}事件中使用BackgroundWorker
,您正在UI线程中执行整个操作;这是DoWork
生来就是为了避免这样做。
此外,由于您正在访问一个BackgroundWorker
的UI对象,因此从调度程序中解包您的代码会出错。
只需使用:
txtQueryfolder
当您调用private void workerextract_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
string queryFolder = e.Argument.ToString();
try
{
DirectoryInfo di = new DirectoryInfo(queryFolder);
files = di.GetFiles("*.sql").Count();
currentfile = 0;
foreach (FileInfo fi in di.GetFiles("*.sql"))
{
// Open the text file using a stream reader.
using (StreamReader sr = new StreamReader(fi.FullName))
{
// Read the stream to a string, and write the string to the console.
string line = sr.ReadToEnd();
//System.Windows.MessageBox.Show(line);
// ExtractToCSV shouldn't access to a UI object.
ExtractToCSV(line, System.IO.Path.GetFileNameWithoutExtension(fi.Name));
currentfile++;
}
int percentage = (currentfile + 1) * 100 / files;
workerextract.ReportProgress(percentage);
}
}
catch (Exception ex)
{
// Don't use MessageBox in a thread different from the UI one. Just set the result (e.Result) and get that in the RunWorkerCompleted event.
// System.Windows.MessageBox.Show(ex.Message);
}
}
方法时,只需添加如下参数:
RunWorkerAsync
答案 1 :(得分:0)
问题在于将整个DoWork包装在Dispatcher.Invoke中。 我需要只包含那些与UI交互的代码。 所以我适当地改变了代码并且它有效。
private void workerextract_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
try
{
this.Dispatcher.Invoke(() =>
{
di = new DirectoryInfo(txtQueryfolder.Text);
});
files = di.GetFiles("*.sql").Count();
currentfile = 0;
foreach (FileInfo fi in di.GetFiles("*.sql"))
{
// Open the text file using a stream reader.
using (StreamReader sr = new StreamReader(fi.FullName))
{
// Read the stream to a string, and write the string to the console.
string line = sr.ReadToEnd();
this.Dispatcher.Invoke(() =>
{
//System.Windows.MessageBox.Show(line);
ExtractToCSV(line, System.IO.Path.GetFileNameWithoutExtension(fi.Name));
});
currentfile++;
}
int percentage = (currentfile + 1) * 100 / files;
workerextract.ReportProgress(percentage);
}
}
catch(Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
感谢所有人展示方向。