如何在catch块中处理InvalidOperationException

本文关键字:处理 InvalidOperationException catch | 更新日期: 2023-09-27 18:13:35

我有使用BackgroundWorker从excel表读取信息并将其上传到数据库的代码,同时还显示通知用户进度的表单。这是一个c#项目。

然而,在我的try/catch语句中,读取excel文件并上传它们,我希望能够关闭进度表单,因为它不再有用了。

当我调用BackgroundWorker类的。close()方法时,会触发InvalidOperationException,我不确定如何处理这种情况。有办法处理吗?还有别的办法关上窗户吗?

这是我的捕获块(位于DoWork事件中):

catch (Exception ex)
{
    MessageBox.Show("Error Uploading Data. See log for details.", "Database Submission Error", MessageBoxButtons.OK);
    // Cancel operation
    backgroundWorker1.CancelAsync();
    // Close form
    progress.Close();
}

backgroundWorker1是BackgroundWorker读取/上传数据,progress是显示进度条和计数已完成/剩余信息的窗口。

例外:

类型为'System '的异常。在System.Windows.Forms.dll中发生了InvalidOperationException,但没有在用户代码中处理。附加信息:跨线程操作无效:控制'ProgressForm'从创建它的线程以外的线程访问。

如何在catch块中处理InvalidOperationException

您不能在DoWork事件中做任何事情,直接触及UI线程,包括关闭(我假设)您在运行线程之前创建的窗体。这里有一个基本的"流程"供你遵循:

  1. 创建一个进度表单的新实例并显示它

  2. 不要在DoWork事件中捕捉异常,除非你打算纠正导致它们的情况。否则,异常将停止工作线程并落入RunWorkerCompleted事件,该事件发生在UI线程上。

  3. 检查RunWorkerCompleted事件中的e.Error…如果不是null,则存在异常,您可以采取适当的操作,例如通知用户。因为这个事件回到UI线程,你也可以关闭你的Form。

试试这个:(动态编写,编译时应该做一些调整)

var progress = new MyProgressForm();
progress.Show();
backgroundWorker1.RunWorkerAsync();
...
...
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
        // log the exception
        MessageBox.Show("Error Uploading Data. See log for details.",
                        "Database Submission Error", MessageBoxButtons.OK);
        // we're back on the UI thread, so we can touch UI elements
        progress.Close();
        return;
    }
    // stuff to do if no error occurred
    ...
}