C#Backgroundworker - 在运行代码时显示表单,在代码完成后关闭

时间:2018-04-24 09:45:33

标签: c# backgroundworker

我有一个用于Excel主从导出的方法,该方法在button_click中处理。方法在3个单独的线程中运行,以获得更快的性能。我想显示一个表单,通知用户有关数据处理的信息(不是进度条表单,只是带有图像的表单)。使用backgroundworker表单可以很好地打开而不会阻止UI线程,但是当我需要时,我无法关闭它 - 在Excel导出方法完成之后。

第一次尝试:

  private void Button1_Click(object sender, EventArgs e)
  {
            alert = new process_form();
            alert.ShowDialog();
            bw.DoWork += (s, ea) =>
            {
                // Error: current thread must be set to single thread apartment(STA) mode before OLE calls can be made.

                //Method for Excel export - It runs in async
                ExportData();

                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.WaitForPendingFinalizers();
            };
            bw.RunWorkerCompleted += (s, ea) =>
            {
                //close form
                this.Invoke(new System.Action(() => { alert.Close(); }));
            };
            bw.RunWorkerAsync();
    }

第二次尝试 - 没有错误,但我无法关闭表格:

  private void Button1_Click(object sender, EventArgs e)
  {
        backgroundWorker1.RunWorkerAsync();

        //Method for Excel export
        ExportData();

        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        GC.WaitForPendingFinalizers();
  }

  private void ExportData()
  {
    //...

    //Cancel async just before SaveFileDialog shows
    backgroundWorker1.CancelAsync();

    SaveFileDialog save_export = new SaveFileDialog();
    if (save_export() == DialogResult.OK)
    {
      //...
    }
  }

  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
  {
            if ((backgroundWorker1.CancellationPending == true))
            {
                alert.Close();
                e.Cancel = true;
            }
            else
            {
                alert = new process_form();
                alert.ShowDialog();
            }
    }

我也尝试过创建一个新的Thread并从那里打开一个表单,然后调用Thread.Abort(),但这会产生一些不希望的结果 - 例如,当process_form关闭时,任何底层的Windows窗口都会成为应用程序之上的顶层窗口。所以背景工作者是我想要的解决方案。

1 个答案:

答案 0 :(得分:0)

解决。我放弃了BGW并做了以下事情:

  1. 打开表单" process_form" (" alert" instance);
  2. 在异步中包装ExportData并运行它;
  3. 在ExportData中,
  4. ,在打开SaveFileDialog之前:
  5. this.Invoke((MethodInvoker)delegate
       {
          alert.Close();
         SaveFileDialog save_export = new SaveFileDialog
         {
          //...
         }
        });
    

    看起来需要在另一个线程中打开SaveFiledialog,这在我的案例中可能是一个问题。谢谢你的帮助!