私のwinformsプロジェクトでは、BackgroundWorkerを実行するフォームを取得しました。基本的にはシミュレーションなので、ある時点で解決できますが、ユーザーが停止することもできるため、いずれかの方法で終了すると、結果を再描画する必要があります。メイン ウィンドウを閉じるとその参照が null になるという事実に問題がありましたが、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);
}
ReportProgress:
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() メソッドが起動されていませんか?
何かお役に立てば幸いです。