1

我有一个水晶报表,它从带有 TreeView 的表单上的按钮从各种 DataTables 生成。我想运行一个 BackGroundWorker,这样我就可以添加一个 ProgressBar,因为生成的 Crystal Report 需要一些时间。我已经读过,首先我需要在控件中添加一个 BackGroundWorker,并将生成 que 长时间运行进程的所有逻辑代码放在 BackGroundWorker 的 DoWork 事件上。我是这样做的:

//bgwBackThread is the name of the BackGroundWorkerObject
private void bgwBackThread_DoWork(object sender, DoWorkEventArgs e)
    {
        DataTable reporte = preReportDouble(Ot, Oth);
        DataTable hh = reporteHH(Ot, Oth);
        DataTable otNoCosto = otNoCost(Ot, Oth);
        DataTable dethh = detalleHH(Ot, Oth);

        //cryrepo is a Form which holds a CrystalReportViewer
        InformeMaquina cryrepo = new InformeMaquina();
        cryrepo.Informe = reporte;
        cryrepo.Hh = hh;
        cryrepo.SinCosto = otNoCosto;
        cryrepo.DetHh = dethh;
        cryrepo.Show();
    }

在我将方法 RunWorkerAsync() 分配给之前生成表单的按钮之后

   private void btnReporte_Click(object sender, EventArgs e)
    {
        bgwBackThread.RunWorkerAsync();
        //Below its commented because before of trying BackGroundWorker I just used the code here.
        /*DataTable reporte = preReportDouble(Ot, Oth);
        DataTable hh = reporteHH(Ot, Oth);
        DataTable otNoCosto = otNoCost(Ot, Oth);
        DataTable dethh = detalleHH(Ot, Oth);

        InformeMaquina cryrepo = new InformeMaquina();
        cryrepo.Informe = reporte;
        cryrepo.Hh = hh;
        cryrepo.SinCosto = otNoCosto;
        cryrepo.DetHh = dethh;
        cryrepo.Show();
        */
    }

问题是当我使用上面的代码按下报告按钮时。它加载包含que Crystal Report 的表单,但此表单挂起(即使在调试中)。不使用 BackGroundWorker 它工作正常,但有延迟。我读过这可能是因为我正在从非 UI 线程加载表单,并且我必须从 UI 取消绑定然后重新绑定。是这个问题吗??如果是,我该如何解除绑定然后重新绑定?

非常感谢您的帮助。

4

1 回答 1

1

尝试在您的表单中创建一个私有类来保存 DataTable 信息(我认为这是耗时的部分);

private class ReportTables {
  public DataTable reporte;
  public DataTable hh;
  public DataTable otNoCosto;
  public DataTable dethh;
}

创建 DataTables 并更新 e.Result 属性中的结果:

private void bgwBackThread_DoWork(object sender, DoWorkEventArgs e)
{
  ReportTables rt = new ReportTables();
  rt.reporte = preReportDouble(Ot, Oth);
  rt.hh = reporteHH(Ot, Oth);
  rt.otNoCosto = otNoCost(Ot, Oth);
  rt.dethh = detalleHH(Ot, Oth);
  e.Result = rt;
}

然后在 Completed 事件中,显示表单:

void bgwBackThread_RunWorkerCompleted(object sender, 
                                      RunWorkerCompletedEventArgs e) {
  if (e.Error != null) {
    MessageBox.Show(e.Error.Message);
  } else {
    ReportsTables rt = e.Result as ReportTables;

    //cryrepo is a Form which holds a CrystalReportViewer
    InformeMaquina cryrepo = new InformeMaquina();
    cryrepo.Informe = rt.reporte;
    cryrepo.Hh = rt.hh;
    cryrepo.SinCosto = rt.otNoCosto;
    cryrepo.DetHh = rt.dethh;
    cryrepo.Show();
  }
}
于 2013-11-13T14:15:15.583 回答