Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a project-wide exception handler in my Windows CE app that is logging this when my app crashes in a specific scenario:

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)

So the problem seems to be in FrmDelivery.ReaderForm_Activated(), which is part of the form's code to deal with barcode scanning:

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();
    }
}

In context, here is the entire barcode scanning-related code on that form:

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;
    }
}

...and here is the code that is called prior to the exception occurring. "Reached frmDelivery.buttonSave_Click" is logged, and I do see the "Delivery saved" but the app crashes immediately thereafter:

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");
}

...and here is an excerpt of the log file (from the time SaveWorkTableRecord() is called until the "deluge"):

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

Pay no attention to the dates; the handheld device is (somewhat fittingly) living in the past.

Here is the last successfully called method:

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);
}

So why is barcodeReader and/or barcodeReaderData (apparently) null, when they are instantiated in InitReader(), which is called when the form is constructed?

UPDATE

Even with the barcodereader and barcodereaderData code moved from where it was to FormClosing(), I still get an 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()

UPDATE 2

Update: I moved this code to FormClosing(), but then got an NRE on shutting down the app...?!? Commenting the code out there, too (barcodeReader and barcodeReaderData no longer being disposed/nullified anywhere) rectified the problem - no more NREs.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
134 views
Welcome To Ask or Share your Answers For Others

1 Answer

Commenting out the code that disposes the barcodeReader and barcodeReaderData objects does the trick:

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;
    //}
}

...but should I dispose/nullify these on formClosing or formClose, or is that moot by then?

Update: I moved this code to FormClosing(), but then got an NRE on shutting down the app...?!? Commenting the code out there, too (barcodeReader and barcodeReaderData no longer being disposed/nullified anywhere) rectified the problem - no more NREs.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...