我使用的是WPF,我的主线程是GUI(向导)。
当用户在向导上单击“完成”时,它会打开显示后台工作程序中使用的用户进度条的第二个线程。
在我正在做的主线程中:
5
在每个createFiles方法中,我将名为currentStep的静态变量加1,我在后台worker中使用它,如下所述。
我在做后台工作者:
MessageWithProgressBar progress = new MessageWithProgressBar();
progress.Show();
createFilesInA();
createFilesInB();
createFilesInC();
createFilesInD();
createFilesInE();
createFilesInF();
createFilesInG();
createFilesInH();
createFilesInI();
createFilesInJ();
createFilesInK();
主线程更新变量名为currentStep,第二个线程用它来报告主线程进度。
主线程的操作需要几秒钟(不超过15秒)
我有两个问题:
只有当currentStep = 2(然后进度为16)然后进度为100时我才会在进度条上看到,我看不到每一步
一开始,进度条冻结,似乎卡住了。
(也许它从主线程连接到调用progress.Show()?)
谢谢!
答案 0 :(得分:2)
据我了解您的代码,您的后台工作人员并没有做任何事情。它会更新进度一次,就是这样。
另外:使用全局静态变量在表单和后台工作程序之间进行通信 - 哎呀......
另外,在我看来你错了。工作(CreateFilesInA
... CreateFilesInK
)应由后台工作人员完成 - 这就是它的用途。由于主线程将以您实现它的方式被阻止,否则您将看不到任何更新。
实现这样的通常方法是:
DoWork
中执行操作的后台工作程序。在DoWork
中,在每次调用CreateFilesInXYZ
方法后,请致电ReportProgress
更新UI。ProgressChanged
事件被触发时更新正在进行中的内容你这样做的方式绝不是异步的。实际上,您的代码看起来应该是这样的:
public partial class MainWindow : Window
{
private BackgroundWorker backgroundWorker = new BackgroundWorker();
private MessageWithProgressBar progressWindow;
public MainWindow()
{
InitializeComponent();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.ProgressChanged += ProgressChanged;
backgroundWorker.DoWork += DoWork;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
progressWindow = new MessageWithProgressBar();
progressWindow.Owner = this;
progressWindow.Show();
backgroundWorker.RunWorkerAsync();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = (BackgroundWorker)sender;
int numSteps = 11;
int currentStep = 0;
int progress = 0;
CreateFilesInA();
currentStep += 1;
progress = (int)((float)currentStep / (float)numSteps * 100.0);
worker.ReportProgress(progress);
CreateFilesInB();
currentStep += 1;
progress = (int)((float)currentStep / (float)numSteps * 100.0);
worker.ReportProgress(progress);
// All other steps here
...
}
private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressWindow.progress.Value = e.ProgressPercentage;
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressWindow.Close();
WindowMsgGenDB msg = new WindowMsgGenDB();
msg.Show();
}
}
请注意,上面的代码会进入您的主窗口! MessageWithProgressWindow
不包含任何代码。也许Window_Loaded
事件处理程序不是启动后台工作程序的正确位置,但是您可以了解它。