在我的 winforms 项目中,我得到了一些运行 BackgroundWorker 的表单。基本上它是一个模拟,所以它可以在某个时候解决,但它也可以由用户停止,所以当它完成任何一种方式时,它都需要重新绘制结果。我遇到了一个问题,即当我关闭主窗口时,它的引用变为空,但 BW 仍然可以触发 ReportProgress,最终出现异常。
我的 BackgroundWorker(简化代码):
void backgroundWorkerRunSimulation_DoWork(object sender, DoWorkEventArgs e)
{
bool ShouldContinue = true;
do
{
SomeHeavyComputing();
if(CheckIfSimulationDone() | backgroundWorkerRunSimulation.CancellationPending)
ShouldContinue=false;
//Redrawing results on the interface
if (AlwaysRefresh | !ShouldContinue)
UpdateGUI(); //<--Method invoked on form's thread
//Reporting progress
backgroundWorkerRunSimulation.ReportProgress(0, SomeReportingObject);
}
while(ShouldContinue);
}
和报告进度:
private void backgroundWorkerRunSimulation_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
UpdateStatusBar((GUIReportInfo)e.UserState);//<-also invoked on form's thread
}
在哪里
void UpdateStatusBar(GUIReportInfo ReportInfo)
{
if (this.InvokeRequired)
{
ReportInfoDelegate updateStatusBar = new ReportInfoDelegate(UpdateStatusBar);
this.Invoke(updateStatusBar, new object[] { ReportInfo });
}
else
//Some assignments on form - crashes here, null reference exc
}
显然 UpdateStatusBar 不应该被触发,我很惊讶 UpdateGUI(这是类比的)不会崩溃。但是有什么方法可以检查表格是否还在?添加:
this.Invoke(new MethodInvoker(delegate { this.Close(); }));
到 FormClosing 事件似乎解决了这个问题,虽然我不明白为什么会这样。无论如何,Close() 方法是否不会在表单的线程上触发?
我很乐意提供任何帮助。