成功操作后为什么会出现这种NRE?

时间:2014-12-24 17:43:28

标签: c# event-handling nullreferenceexception barcode barcode-scanner

我的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()

更新2

更新:我将此代码移至FormClosing(),但在关闭应用程序时得到了NRE ......?!?在那里评论代码(barcodeReader和barcodeReaderData不再在任何地方处理/无效)纠正了问题 - 不再有NRE。

1 个答案:

答案 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。