使用 BackgroundWorker 处理异常

Handling exception with BackgroundWorker

在 WinForms 应用程序中,当触发 BackgroundWorker.DoWork 事件时,运行 的方法中出现异常。

System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();
worker.DoWork += import_begin;
System.Objects arguments = new System.Object[] {filename, why};
worker.RunWorkerAsync(arguments);

private void import_begin(System.Object sender, System.ComponentModel.DoWorkEventArgs args)
{
    // unpack the arguments
    System.String filename = (System.String)arguments[0];

    // exception is occurring here
    Controller.Excel excel = new Controller.Excel(filename);
}

我设置了断点来确定抛出异常的位置,它在上面注释的代码行中。即使在处理异常之后,也会出现一个对话框:

"Exception has been thrown by the target of an invocation".

是否可以阻止此对话框?

顺便说一下,由于尝试导入的文件类型无效,异常类型为 InvalidDataException

编辑:部分Controller.Excel代码:

class Excel
{
    protected OfficeOpenXml.ExcelPackage excel;
        protected const int HEADER_ROW_OFFSET = 7;
        System.Globalization.CultureInfo provider;

        // ctor
        public Excel(System.String filename)
        {

            excel = new OfficeOpenXml.ExcelPackage(new System.IO.FileInfo(filename));
            excel.Compatibility.IsWorksheets1Based = false;
            provider = System.Globalization.CultureInfo.InvariantCulture;

        }
}

OP:

it is using the standard file dialog form. It is intended for the user to open an .xlsx file, and this exception occurs whenever they try to open any other file type

我听起来好像你只是想优雅地处理当用户以某种方式选择一个不是 Excel 文件 and/or 损坏的文件时的情况。

将您的代码更改为:

private void import_begin(System.Object sender, System.ComponentModel.DoWorkEventArgs args)
{
    // unpack the arguments
    System.String filename = (System.String)arguments[0];

    // you probably should inspect the file extension in `filename` to see if it
    // is at least .xls or .xlsx prior to using Controller

    try
    {   
        Controller.Excel excel = new Controller.Excel(filename);
        ...        
    }
    catch (InvalidDataException ex)
    {
        // gracefully handle the error
        ...
    }
    catch (Exception ex)
    {
        // eat, don't want thread to unwind
    }
}

现在,如果他们选择任何其他文件类型或文件是损坏的 Excel 文件,将调用上面的 catch 处理程序,您可以从容地处理这种情况。

通常你不应该从 worker 更新 UI 但 MessageBox 有它自己的消息泵。

提示

为了保持整洁,您可能需要在 运行 BackgroundWorker 之前检查文件的扩展名。这是一种快速检查,可以快速取胜,并将所有 UI 相关活动保留在主线程中,而不是子线程中,这样事情会变得更复杂。