在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);
}
我已经设置了断点来确定引发异常的位置,并且该异常在上面提到的代码行中。即使在处理完异常之后,仍会显示一个对话框:
“调用目标已引发异常”。
是否可以阻止此对话框?
顺便说一句,由于尝试导入的文件类型无效,因此异常类型为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:
它使用的是标准文件对话框形式。它旨在供用户打开.xlsx文件,并且当他们尝试打开任何其他文件类型
时,会发生此异常。
听起来好像您只是想在用户以某种方式选择不是Excel文件和/或损坏的文件时优雅地处理条件。
将您的代码更改为类似的内容:
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
// In this example we inform the user
MessageBox.Show ("That file does not appear to be an Excel file");
}
}
现在,如果他们选择任何其他文件类型,或者该文件是损坏的Excel文件,则将调用上面的catch
处理程序,您可以在该处优雅地处理此情况。
通常,您不应该从worker更新UI,但是MessageBox
有它自己的消息泵。
为了保持整洁,您可能需要在运行BackgroundWorker
之前检查文件的扩展名。这是一项快速检查,以快速获胜,并将所有与UI相关的活动都保留在主线程中,而不是使事情变得更加复杂的子线程。