我正在使用Apache PDFBox将.pdf文档转换为文本文件,使用PDFTextStripper WinForms C#应用程序。
我发现转换大约需要30秒才能完成。我想要做的是在C#progressBar中显示转换给用户的进度。
我已经在程序中添加了backgroundWorker线程以及事件处理程序。 但是,当我在backgroundWorker1_DoWork中调用PDFTextStripper时,progressBar不报告任何 进行直到转换发生之后。 (示例代码如下所示)
有人能建议一个更好的方法来显示progressBar1中的进度吗?谢谢。
将我的.pdf文件复制到其位置后,检查文件是否已成功复制,然后调用转换方法。
if (File.Exists(@"C:\My PDF Folder\myFile.pdf))
{
string myFile = @"C:\My PDF Folder\myFile.pdf";
Tuple<string> tuple = Tuple.Create(myFile);
backgroundWorker1.RunWorkerAsync(tuple);//convert from .pdf to .txt file.
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i += 20)
{
Tuple<string> tupleArgs = (Tuple<string>)e.Argument;
string myFile = tupleArgs.Item1.ToString();
string tempText = PDFText(myFile);//The PDFTextStripper method
//Report the progress
backgroundWorker1.ReportProgress(i);
SaveFileDialog sfd = new SaveFileDialog();
sfd.FileName = @"C:\My PDF Folder\myFile.txt";
using (Stream s = File.Open(sfd.FileName, FileMode.OpenOrCreate))
using (StreamWriter sw = new StreamWriter(s))
sw.Write(tempText);
}
}
private static String PDFText(String PDFFilePath)
{
PDDocument doc = PDDocument.load(PDFFilePath);
PDFTextStripper stripper = new PDFTextStripper();
string text = stripper.getText(doc);
doc.close();
return text;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//Change the value of the ProgressBar to the BackgroundWorker progress.
progressBar1.Value = e.ProgressPercentage;
}
public void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar1.Value = 0;
}
答案 0 :(得分:0)
看起来你已经把事情搞定了。当你在BackgroundWorker
线程中发生了大量的事情时,它仍然发生在一个线程中,一行代码接着另一个。你不会锁定你的UI线程,这很好,但你仍然需要等待一行代码在另一行运行之前运行。
考虑到您的代码,PDFText()
中发生的任何事情必须在下一行运行之前完成,并将进度报告回UI线程(这是ReportProgress()
所做的):
string tempText = PDFText(myFile);
backgroundWorker1.ReportProgress(i);
只需翻转两行,即可在PDFText()
执行长时间运行之前立即报告进度:
backgroundWorker1.ReportProgress(i);
string tempText = PDFText(myFile);
另一个观察......没有必要在这里实例化SaveFileDialog
。只需直接使用文件路径:
using (Stream s = File.Open(@"C:\My PDF Folder\myFile.txt", FileMode.OpenOrCreate))
using (StreamWriter sw = new StreamWriter(s))
sw.Write(tempText);
更好,甚至更短:
File.WriteAllText(@"C:\My PDF Folder\myFile.txt", tempText); // overwrite the file
File.AppendAllText(@"C:\My PDF Folder\myFile.txt", tempText); // or append to the file