我的Windows CE应用程序中有一个项目范围的异常处理程序,当我的应用程序在特定情况下崩溃时会记录此异常处理程序:
Message: From application-wide exception handler: System.NullReferenceException: NullReferenceException
at HHS.FrmDelivery.ReaderForm_Activated(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnActivated(EventArgs e)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.DLG.MessageBox(String wszCaption, String wszBody, MessageBoxButtons mbtyp, MessageBoxIcon mbicon, MessageBoxDefaultButton defbtn, DialogResult& mbret)
at System.Windows.Forms.MessageBox.Show(String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
at HHS.FrmDelivery.buttonSave_Click(Object sender, EventArgs args)
所以问题似乎出现在FrmDelivery.ReaderForm_Activated()中,这是处理条形码扫描的表单代码的一部分:
private void ReaderForm_Activated(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.ReaderForm_Activated");
// If there are no reads pending on barcodeReader start a new read
if (!this.barcodeReaderData.IsPending)
{
this.StartRead();
}
}
在上下文中,这是与该表格上的整个条形码扫描相关的代码:
public partial class FrmDelivery : Form
{
. . .
// Barcode stuff
private Symbol.Barcode.Reader barcodeReader;
private Symbol.Barcode.ReaderData barcodeReaderData;
private EventHandler barcodeEventHandler;
// </ Barcode stuff
// form's overloaded constructor
public FrmDelivery(NewDelivery newDel)
{
InitializeComponent();
. . .
textBoxUPC_PLU.Focus();
}
// Barcode scanning code
private void textBoxUPC_PLU_GotFocus(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.textBoxUPC_PLU_GotFocus");
if (this.InitReader())
{
this.StartRead();
}
}
private bool InitReader()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.InitReader");
// If reader is already present then retreat
if (this.barcodeReader != null)
{
return false;
}
// Create new reader, first available reader will be used.
this.barcodeReader = new Symbol.Barcode.Reader();
// Create reader data
this.barcodeReaderData = new Symbol.Barcode.ReaderData(
Symbol.Barcode.ReaderDataTypes.Text,
Symbol.Barcode.ReaderDataLengths.MaximumLabel);
// Create event handler delegate
this.barcodeEventHandler = this.BarcodeReader_ReadNotify;
// Enable reader, with wait cursor
this.barcodeReader.Actions.Enable();
this.barcodeReader.Parameters.Feedback.Success.BeepTime = 0;
this.barcodeReader.Parameters.Feedback.Success.WaveFile = "\\windows\\alarm3.wav";
// Attach to activate and deactivate events
this.Activated += ReaderForm_Activated;
this.Deactivate += ReaderForm_Deactivate;
return true;
}
private void StartRead()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.StartRead");
// If we have both a reader and a reader data
if ((this.barcodeReader != null) && (this.barcodeReaderData != null))
{
// Submit a read
this.barcodeReader.ReadNotify += this.barcodeEventHandler;
this.barcodeReader.Actions.Read(this.barcodeReaderData);
}
}
private void BarcodeReader_ReadNotify(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.BarcodeReader_ReadNotify");
Symbol.Barcode.ReaderData TheReaderData = this.barcodeReader.GetNextReaderData();
// If it is a successful read (as opposed to a failed one)
if (TheReaderData.Result == Symbol.Results.SUCCESS)
{
// Handle the data from this read
this.HandleData(TheReaderData);
// Start the next read
this.StartRead();
}
}
private void ReaderForm_Activated(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.ReaderForm_Activated");
// If there are no reads pending on barcodeReader start a new read
if (!this.barcodeReaderData.IsPending)
{
this.StartRead();
}
}
private void ReaderForm_Deactivate(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.ReaderForm_Deactivate");
this.StopRead();
}
private void HandleData(Symbol.Barcode.ReaderData readerData)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.HandleData");
textBoxUPC_PLU.Text = readerData.Text;
// now move off of it to next non-read-only textBox
textBoxPackSize.Focus();
}
private void StopRead()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.StopRead");
// If we have a reader
if (this.barcodeReader != null)
{
// Flush (Cancel all pending reads)
this.barcodeReader.ReadNotify -= this.barcodeEventHandler;
this.barcodeReader.Actions.Flush();
}
}
private void textBoxUPC_PLU_LostFocus(object sender, EventArgs e)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.textBoxUPC_PLU_LostFocus");
this.DisposeBarcodeReaderAndData();
}
private void DisposeBarcodeReaderAndData()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.DisposeBarcodeReaderAndData");
// If we have a reader
if (this.barcodeReader != null)
{
// Disable the reader
this.barcodeReader.Actions.Disable();
// Free it up
this.barcodeReader.Dispose();
// Indicate we no longer have one
this.barcodeReader = null;
}
// If we have a reader data
if (this.barcodeReaderData != null)
{
// Free it up
this.barcodeReaderData.Dispose();
// Indicate we no longer have one
this.barcodeReaderData = null;
}
}
...这里是在发生异常之前调用的代码。记录了“达到frmDelivery.buttonSave_Click”,我确实看到“已保存交付”,但应用程序此后立即崩溃:
private void buttonSave_Click(object sender, EventArgs args)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.buttonSave_Click");
if (RequiredDataMissing())
{
this.IndicateMissingData();
return;
}
this.PrepareForNewDSDTable();
SaveDSDHeaderRecord();
SaveWorkTableRecord();
// Now can search the record
buttonFind.Enabled = true;
MessageBox.Show("Delivery saved");
}
...这里是日志文件的摘录(从SaveWorkTableRecord()调用到“大洪水”):
Date: 3/13/2009 6:41:34 PM
Message: Reached frmDelivery.SaveWorkTableRecord
Date: 3/13/2009 6:41:34 PM
Message: Reached HHSUtils.TryConvertToInt32
Date: 3/13/2009 6:41:34 PM
Message: Reached HHSUtils.TryConvertToDecimal
Date: 3/13/2009 6:41:34 PM
Message: Reached SQliteHHSDBUtils.InsertWorkTableRecord
Date: 3/13/2009 6:41:34 PM
Message: Reached HHSUtils.GetDBConnection
Date: 3/13/2009 6:41:34 PM
Message: Reached frmDelivery.ReaderForm_Deactivate
Date: 3/13/2009 6:41:34 PM
Message: Reached frmDelivery.StopRead
Date: 3/13/2009 6:41:37 PM
Message: Reached frmDelivery.ReaderForm_Activated
Date: 3/13/2009 6:41:37 PM
Message: From application-wide exception handler: System.NullReferenceException: NullReferenceException
at HHS.FrmDelivery.ReaderForm_Activated(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnActivated(EventArgs e)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.DLG.MessageBox(String wszCaption, String wszBody, MessageBoxButtons mbtyp, MessageBoxIcon mbicon, MessageBoxDefaultButton defbtn, DialogResult& mbret)
at System.Windows.Forms.MessageBox.Show(String text, String caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton)
at HHS.FrmDelivery.buttonSave_Click(Object sender, EventArgs args)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.ButtonBase.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at HHS.Program.Main()
不注意日期;手持设备(有点合适)生活在过去。
这是最后一个成功调用的方法:
private void SaveWorkTableRecord()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.SaveWorkTableRecord");
WorkTable wt = new WorkTable
{
WTName = this.dsdName,
SiteNum = this.nd.SiteNum,
FileType = "DSD",
FileDate = this.nd.DeliveryDate,
TotalItems = HHSUtils.TryConvertToInt32(this.textBoxQty.Text.Trim()),
TotalAmount =
HHSUtils.TryConvertToDecimal(this.textBoxTotalDollar.Text.Trim())
};
hhsdbutils.InsertWorkTableRecord(wt);
}
那么为什么barcodeReader和/或barcodeReaderData(显然)是null,当它们在InitReader()中实例化时,在构造表单时调用它?
即使条形码阅读器和barcodereader数据代码从FormClosing()移动到了,我仍然得到一个NRE:
Date: 3/13/2009 8:10:08 PM
Message: Reached frmDelivery.DisposeBarcodeReaderAndData
Date: 3/13/2009 8:10:08 PM
Message: Reached HHSUtils.TextBoxLostFocus
Date: 3/13/2009 8:10:08 PM
Message: Reached frmDelivery.buttonClose_Click
Date: 3/13/2009 8:10:12 PM
Message: Reached frmDelivery.ReaderForm_Deactivate
Date: 3/13/2009 8:10:12 PM
Message: Reached frmDelivery.StopRead
Date: 3/13/2009 8:10:13 PM
Message: Reached frmDelivery.BarcodeReader_ReadNotify
Date: 3/13/2009 8:10:13 PM
Message: From application-wide exception handler: System.NullReferenceException: NullReferenceException
at HHS.FrmDelivery.BarcodeReader_ReadNotify(Object sender, EventArgs e)
at System.Windows.Forms.Control.TASK.Invoke()
at System.Windows.Forms.Control._InvokeAll()
更新:我将此代码移至FormClosing(),但在关闭应用程序时得到了NRE ......?!?在那里评论代码(barcodeReader和barcodeReaderData不再在任何地方处理/无效)纠正了问题 - 不再有NRE。
答案 0 :(得分:1)
注释掉处理barcodeReader和barcodeReaderData对象的代码可以解决问题:
private void DisposeBarcodeReaderAndData()
{
ExceptionLoggingService.Instance.WriteLog("Reached frmDelivery.DisposeBarcodeReaderAndData");
// Commenting out to see if this prevents the NRE; if so, try moving this to FromClose or FormClosing or something similar
//// If we have a reader
//if (this.barcodeReader != null)
//{
// // Disable the reader
// this.barcodeReader.Actions.Disable();
// // Free it up
// this.barcodeReader.Dispose();
// // Indicate we no longer have one
// this.barcodeReader = null;
//}
//// If we have a reader data
//if (this.barcodeReaderData != null)
//{
// // Free it up
// this.barcodeReaderData.Dispose();
// // Indicate we no longer have one
// this.barcodeReaderData = null;
//}
}
...但是我应该在formClosing或formClose上处理/取消这些,或者那时是不是很有用?
更新:我将此代码移至FormClosing(),但在关闭应用程序时得到了NRE ......?!?在那里评论代码(barcodeReader和barcodeReaderData不再在任何地方处理/无效)纠正了问题 - 不再有NRE。