バックグラウンドワーカーを含む単一のフォームを含むWinFormsアプリがあります。フォームには、RunWorkerAsync()を介してバックグラウンドワーカーを開始するボタンと、アプリケーションを終了する別のボタンが含まれています。約1/3の時間、バックグラウンドワーカーが作業を完了した後、次のような例外を除いて、[終了]ボタンをクリックするとアプリケーションがクラッシュします。
System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=System.Drawing
StackTrace:
at System.Drawing.Graphics.Dispose(Boolean disposing)
at System.Drawing.Graphics.Finalize()
アプリケーションを終了するボタンのイベントハンドラーは次のとおりです。
private void buttonExit_Click(object sender, EventArgs e)
{
if (!buttonStartWorker.Enabled)
{
DialogResult dr = MessageBox.Show("Background worker is still running! Exit anyway?", "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dr == DialogResult.OK)
{
backgroundWorker.CancelAsync();
Close();
}
}
else
{
Close();
}
}
前に述べたように、バックグラウンドワーカーがまだ実行されている間はアプリケーションを終了しないので、ここで見ているコードパスはClose()呼び出しだけです。USB関連のハンドルでcloseメソッドとdisposeメソッドを呼び出すFormClosingイベントハンドラーもあります。そのコードは次のとおりです。
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
// close and dispose all open handles to the USB device
if (hidHandle != null)
{
if (!(hidHandle.IsInvalid))
{
hidHandle.Close();
hidHandle.Dispose();
}
}
if (readHandle != null)
{
if (!(readHandle.IsInvalid))
{
readHandle.Close();
readHandle.Dispose();
}
}
if (writeHandle != null)
{
if (!(writeHandle.IsInvalid))
{
writeHandle.Close();
writeHandle.Dispose(); // unhandled exception seems to occur after this
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
writeHandle.Dispose()とアプリケーションが実際に終了する時間の間のある時点で、この例外が発生しています。私を最も混乱させているのは、私のコードがSystem.Drawingを明示的に使用していないため、これを追跡するのに問題があるという事実です。
その価値について、私のバックグラウンドワーカーは次のことを行います。
- USBデバイスとの間でデータの読み取りと書き込みを行います
- いくつかのデータをダウンロードするためのWebクライアントを作成します
- それはいくつかのSOAP呼び出しを行います
アプリケーション(System.Drawingを明示的に使用していない)が終了したときに、System.Drawingで未処理のNullReferenceExceptionが発生する原因について誰かが考えていますか?