我的代码使用BackgroundWorker从Excel工作表中读取信息并将其上传到数据库,同时还显示一个表单,通知用户进度。这是一个C#项目。
但是,在我的try / catch语句中读取excel文件并上传它们,我希望能够关闭进度表单,因为它不再有用。
当我调用BackgroundWorker类的.Close()方法时,会触发InvalidOperationException,我不知道如何处理这种情况。有办法处理吗?还有另一种关闭窗户的方法吗?
这是我的catch块(位于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.Windows.Forms.dll中发生了'System.InvalidOperationException'类型的异常但未在用户代码中处理附加信息:跨线程操作无效:从线程以外的线程访问控制'ProgressForm'它创建于。
答案 0 :(得分:2)
您无法在直接触及UI线程的DoWork
事件中执行任何操作,包括在运行线程之前关闭您创建的表单(我假设)。这是一个基本的"流程"你可以跟随:
创建进度表单的新实例并显示它。
启动BackgroundWorker。
不要在DoWork
事件中捕获异常,除非您打算纠正导致它们发生的情况。否则,异常将停止工作并进入RunWorkerCompleted
事件,该事件发生在UI线程上。
检查e.Error
活动中的RunWorkerCompleted
...如果它不是null
,那么会有异常,您可以采取适当的措施例如通知用户。由于此事件已返回UI线程,因此您也可以关闭表单。
试试这个:(即时编写,应该通过一些调整进行编译)
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
...
}