C#Backgroundworker-在运行代码时显示表单,并在代码完成后关闭
我有一个Excel主详细信息导出的方法,可以通过单击按钮来处理。方法在3个单独的线程中运行,以提高性能。我想显示一个通知用户数据处理的表单(不是进度条表单,只是一个包含图像的表单)。使用backgroundworker表单可以在不阻塞UI线程的情况下很好地打开,但在Excel导出方法完成后,我无法在需要时关闭它 第一次尝试:C#Backgroundworker-在运行代码时显示表单,并在代码完成后关闭,c#,backgroundworker,C#,Backgroundworker,我有一个Excel主详细信息导出的方法,可以通过单击按钮来处理。方法在3个单独的线程中运行,以提高性能。我想显示一个通知用户数据处理的表单(不是进度条表单,只是一个包含图像的表单)。使用backgroundworker表单可以在不阻塞UI线程的情况下很好地打开,但在Excel导出方法完成后,我无法在需要时关闭它 第一次尝试: private void Button1_Click(object sender, EventArgs e) { alert = new p
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.Abort(),但这会产生一些不希望的结果——例如,当process\u窗体关闭时,任何底层窗口都会变成应用程序上方的顶部窗口。所以backgroundworker是我想要的解决方案。解决了。我放弃了BGW,做了以下事情:
看起来需要在另一个线程中打开SaveFiledialog,在我的例子中,这可能是一个问题。谢谢你的帮助 通过让BGW创建表单,您很可能会将所有内容都放在后面。而是使窗体包含BGW,并使其从Form.Show事件开始。还可以将表单转换为模式对话框。除了针对Windows窗体+BGW的特殊解决方案之外,您还说您正在使用多线程来提高性能。但多线程只对CPU受限的工作有帮助。你对这种情况有多确定?这听起来像是磁盘绑定(excel的I/O)。您的后台工作人员正在将警报显示为对话框,这意味着在关闭警报之前,表单上的所有处理都将停止。因此,您的dowork将检查其未取消并显示一个对话框。。它不再检查cancellation@Christopher,我想我不太明白你的意思,你能给我举个例子吗?…关于ExportData中的多线程-没有多线程,我的xxport运行缓慢-它不仅从DB中捕获数据,而且还设计Excel工作表来删除数据。@BugFinder,修复为just.show()解决不了我的问题。做我的研究让我做到了,但我不能让它同样工作。@Lucy82好的,那么使用那个链接有什么地方不起作用呢?
this.Invoke((MethodInvoker)delegate
{
alert.Close();
SaveFileDialog save_export = new SaveFileDialog
{
//...
}
});