我有一个读取一些数据的程序,然后基于此创建一个大数据表,最后将此数据表导出到.csv文件。由于表的生成需要很长时间,因此我创建了一个后台工作程序,它应该显示在我的mainform上的列表框中,程序正在进行中。
下面是我的代码摘要:
private readonly BackgroundWorker worker = new BackgroundWorker();
public void get_data()
{
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.ProgressChanged += worker_ProgressChanged;
worker.WorkerReportsProgress = true;
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
worker.ReportProgress(1, "Starting");
mydata = read_file();
worker.ReportProgress(1, "Step 1 done!");
fullmodel = combine_data(mydata);
worker.ReportProgress(1, "Step 2 done!");
DataTableToCSV(fullmodel, ';');
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
MainWindow.listBox.Items.Add(e.UserState);
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
当我在VS2015的调试模式下运行我的程序,“正在启动”,“完成第1步”时,这很正常。和“第2步完成!”它们应该出现在列表框中。但是,当我在Visual Studio外部运行应用程序时,ProgressChanged事件似乎只触发一次 - “正在启动”按预期显示在列表框中,但只有在完成后台工作时,才应报告其他两个条目运行会立即显示在列表框中,并且在程序运行时UI会冻结。
答案 0 :(得分:1)
.ReportProgress
,似乎UI线程无法跟上这一点(虽然没有触发异常)。在调试模式下运行程序时,由于某种原因,程序运行速度慢得多,然后UI线程似乎没有这个问题。
答案 1 :(得分:0)
我无法使用空read_file()
,combine_data()
和DataTableToCSV()
方法重现您的方案,因此我认为这可能是此方法的问题。例如,read_file()
可以抛出异常,因为无法在磁盘上找到文件或类似的东西。
抛出后台异常的功能是它不会停止主应用程序。
通过MSDN:
如果操作引发了代码无法处理的异常,则BackgroundWorker会捕获异常并将其传递给RunWorkerCompleted事件处理程序,并将其作为System.ComponentModel .. ::。RunWorkerCompletedEventArgs的Error属性公开。如果您在Visual Studio调试器下运行,则调试器将在DoWork事件处理程序中出现未处理的异常的位置中断。
因此,您可以向worker_RunWorkerCompleted()
方法添加代码并检查Exception
是否被抛出。