我有一个 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() 调用。还有一个 FormClosing 事件处理程序,它在我的 USB 相关句柄上调用 close 和 dispose 方法。该代码如下:
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 的原因有任何想法?