Windows Mobile application with symbol scanner dll crash at close application

3.8k views Asked by At

I have a question that I cant come up with a solution for. Its About my application on a motorola MC3190-G Handheld Application on wm 6.5 and Compact Framework 2.0

After implementation of the Symbol Package for using the scanner trigger inside my application, I get the following error everytime I close my application / or a form which has the scanner enabled: (Even if I never received data from scanning)

I searched for a solution on stackoverflow and other sites with no solutions to fix it.

I am new to mobile application development. I try and catched everything but the error seem to can't be catched with exceptiontype "exception".

sorry for the poor english.

Error:

NullReferenceException

at MainForm.SymbolReader_ReadNotifiy()
at
Task.Invoke()
at
System.Windows.Forms.Control._InvokeAll()
at
System.Windows.Forms.Control.WinProc()

Informations:

Motorola EMDK 2.6 Device: MC3190-G

Sourcecode:

Scanner.cs

namespace MyScann
{
    /// <summary>
    /// Summary description for Scanner.
    /// </summary>
    public class Scanner
    {

        public static Symbol.Barcode.Reader SymbolReader = null;
        public static Symbol.Barcode.ReaderData SymbolReaderData = null;
        public static System.EventHandler SymbolEventHandler = null;
        public static DataSet CodeDataSet;


        //public static Utils.Sound ReadErrorSound;

        public static bool ScannerEnabled = false;
        public static void ActivateScanner()
        {

            // If we have both a reader and a reader-data Object
            if ( Scanner.SymbolReader != null &&
                Scanner.SymbolReaderData != null &&
                ! Scanner.SymbolReaderData.IsPending )
            {
                // Submit 'Read'
                try
                {
                    Scanner.SymbolReader.Actions.Read(Scanner.SymbolReaderData);
                }
                catch (Exception err)
                {
                    MessageBox.Show(err.Message);
                    if ( err.InnerException != null )
                        MessageBox.Show(err.InnerException.Message);
                }
            }

        }
        public static void DeactivateScanner()
        {

            // If we have both a reader and a reader-data Object
            if ( Scanner.SymbolReader != null &&
                Scanner.SymbolReaderData != null &&
                Scanner.SymbolReaderData.IsPending )
            {
                // Submit 'CancelRead'
                try
                {
                    Scanner.SymbolReader.Actions.CancelRead(Scanner.SymbolReaderData);
                }
                catch (Exception err)
                {
                    MessageBox.Show(err.Message);
                    if ( err.InnerException != null )
                        MessageBox.Show(err.InnerException.Message);
                }
            }

        }

        /// <summary>
        /// Initialize the reader.
        /// </summary>
        /// <returns>False if an error accurs</returns>
        public static bool InitSymbolReader()
        {

            // If reader is already present then fail initialize
            if ( SymbolReader != null )
            {
                return false;

            }

            // Create new reader, first available reader will be used.
            SymbolReader = new Symbol.Barcode.Reader();
            // Create reader data
            SymbolReaderData = new Symbol.Barcode.ReaderData(
                Symbol.Barcode.ReaderDataTypes.Text,
                Symbol.Barcode.ReaderDataLengths.DefaultText);

            // set scanner read error sound
            //ReadErrorSound = new Utils.Sound(ErrorSound);

            return true;
        }

        /// <summary>
        /// Stop reading and disable/close reader
        /// </summary>
        public static void DeinitSymbolReader()
        {
            try
            {
                // If we have a reader
                if ( SymbolReader != null )
                {

                    //Cancel Incoming Requests
                    SymbolReader.Actions.Flush();

                    // Disable the reader
                    SymbolReader.Actions.Disable();

                    // Free it up
                    SymbolReader.Dispose();

                    // Indicate we no longer have one
                    SymbolReader = null;
                }

                // If we have a reader data
                if ( SymbolReaderData != null )
                {
                    // Free it up
                    SymbolReaderData.Dispose();

                    // Indicate we no longer have one
                    SymbolReaderData = null;
                }
                if(SymbolEventHandler!=null){
                    //SymbolEventHandler(this,null);
                    SymbolEventHandler = null;
                }
            }
            catch (Exception e){MessageBox.Show(e.StackTrace.ToString());
            }

        }

        /// <summary>
        /// Enable most barcode type with no limitation on length
        /// </summary>
        public static void OpenAllBarcodes()
        {
            SymbolReader.Decoders.CODABAR.Enabled = true;
            SymbolReader.Decoders.CODABAR.MinimumLength = 0;
            SymbolReader.Decoders.CODABAR.MaximumLength = 0;

            SymbolReader.Decoders.CODE11.Enabled = true;
            SymbolReader.Decoders.CODE11.MinimumLength = 0;
            SymbolReader.Decoders.CODE11.MaximumLength = 0;

            SymbolReader.Decoders.CODE39.Enabled = true;
            SymbolReader.Decoders.CODE39.MinimumLength = 0;
            SymbolReader.Decoders.CODE39.MaximumLength = 0;

            SymbolReader.Decoders.CODE93.Enabled = true;
            SymbolReader.Decoders.CODE93.MinimumLength = 0;
            SymbolReader.Decoders.CODE93.MaximumLength = 0;

            SymbolReader.Decoders.CODE128.Enabled = true;
            SymbolReader.Decoders.CODE128.MinimumLength = 0;
            SymbolReader.Decoders.CODE128.MaximumLength = 0;

            SymbolReader.Decoders.DATAMATRIX.Enabled = true;
            SymbolReader.Decoders.DATAMATRIX.MinimumLength = 0;
            SymbolReader.Decoders.DATAMATRIX.MaximumLength = 0;

            SymbolReader.Decoders.D2OF5.Enabled = true;
            SymbolReader.Decoders.D2OF5.MinimumLength = 0;
            SymbolReader.Decoders.D2OF5.MaximumLength = 0;

            SymbolReader.Decoders.I2OF5.Enabled = true;
            SymbolReader.Decoders.I2OF5.MinimumLength = 0;
            SymbolReader.Decoders.I2OF5.MaximumLength = 0;
            /*
        SymbolReader.Decoders.EAN13.Enabled = true;
        SymbolReader.Decoders.EAN13.MinimumLength = 0;
        SymbolReader.Decoders.EAN13.MaximumLength = 0;

        SymbolReader.Decoders.EAN8.Enabled = true;
        SymbolReader.Decoders.EAN8.MinimumLength = 0;
        SymbolReader.Decoders.EAN8.MaximumLength = 0;

        SymbolReader.Decoders.PDF417.Enabled = true;
        SymbolReader.Decoders.PDF417.MinimumLength = 0;
        SymbolReader.Decoders.PDF417.MaximumLength = 0;

        SymbolReader.Decoders.UPCA.Enabled = true;
        SymbolReader.Decoders.UPCA.MinimumLength = 0;
        SymbolReader.Decoders.UPCA.MaximumLength = 0;

        SymbolReader.Decoders.UPCE1.Enabled = true;
        SymbolReader.Decoders.UPCE1.MinimumLength = 0;
        SymbolReader.Decoders.UPCE1.MaximumLength =0;

        SymbolReader.Decoders.UPCE0.Enabled = true;
        SymbolReader.Decoders.UPCE0.MinimumLength = 0;
        SymbolReader.Decoders.UPCE0.MaximumLength = 0;
             */




            SymbolReader.Parameters.CodeIdType = Symbol.Barcode.CodeIdTypes.None;
            SymbolReader.Parameters.ScanType = Symbol.Barcode.ScanTypes.Background;
            SymbolReader.Parameters.LocalFeedback = Symbol.Barcode.DisabledEnabled.Enabled;

            Scanner.SymbolReader.Parameters.Feedback.Success.BeepTime = 0;
        }







    }
}
}

Inside MainForm.cs

    public void InitScanner(byte BatteryLevel)
    {

        // Create event handler delegate
        if (Scanner.MyScann.Scanner.SymbolEventHandler == null)
        {
            Scanner.MyScann.Scanner.SymbolEventHandler = new EventHandler(this.SymbolReader_ReadNotify);
            // Enable reader, with wait cursor
            Scanner.MyScann.Scanner.SymbolReader.Actions.Enable();
            Scanner.MyScann.Scanner.OpenAllBarcodes();
            Scanner.MyScann.Scanner.ScannerEnabled = true;
        }
        // If we have both a reader and a reader data
        if ((Scanner.MyScann.Scanner.SymbolReader != null) &&
            (Scanner.MyScann.Scanner.SymbolReaderData != null))
        {
            // Submit a read
            Scanner.MyScann.Scanner.SymbolReader.ReadNotify += Scanner.MyScann.Scanner.SymbolEventHandler;
            Scanner.MyScann.Scanner.SymbolReader.Actions.Read(Scanner.MyScann.Scanner.SymbolReaderData);
        }
    }

    public void SymbolReader_ReadNotify(object sender, EventArgs e)
    {
        Symbol.Barcode.ReaderData TheReaderData = Scanner.MyScann.Scanner.SymbolReader.GetNextReaderData();
        if (TheReaderData.Result == Symbol.Results.SUCCESS /*&& (txtBarcode.Focused == true)*/)
        {

            //  if (txtBarcode.Focused == true)
            //  {
            //       txtBarcode.Text = TheReaderData.Text.ToString();
            MessageBox.Show(TheReaderData.Text.ToString());
            SymbolReader_CycleScannerReader();
            return;
            //   }
        }
        SymbolReader_CycleScannerReader();
    }

    public void SymbolReader_CycleScannerReader()
    {
        Scanner.MyScann.Scanner.SymbolReader.Actions.Read(Scanner.MyScann.Scanner.SymbolReaderData);
    }

    public void StartScanner()
    {
        bool flag = false;
        try
        {
            Scanner.MyScann.Scanner.SymbolEventHandler = null;
            Scanner.MyScann.Scanner.DeinitSymbolReader();
            Scanner.MyScann.Scanner.ScannerEnabled = false;
            if (!Scanner.MyScann.Scanner.ScannerEnabled)
            {
                Scanner.MyScann.Scanner.SymbolEventHandler = null;
                Scanner.MyScann.Scanner.InitSymbolReader();
                InitScanner(100);
                flag = true;
            }
        }
        catch
        {
            Scanner.MyScann.Scanner.SymbolEventHandler = null;
            Scanner.MyScann.Scanner.InitSymbolReader();
            InitScanner(100);
            flag = true;
        }
        finally
        {
            if (!flag)
            {
                MessageBox.Show("Scanner Error");
            }
        }
    }

    void public void CloseScanner()
    {
        Scanner.MyScann.Scanner.SymbolEventHandler = null;
        Scanner.MyScann.Scanner.DeinitSymbolReader();
    }

void MainFormLoad(object sender, EventArgs e)
    {
        StartScanner();
    }
void MainFormClosing(object sender, System.ComponentModel.CancelEventArgs e)
    {
            CloseScanner();
    }
    void ButtonExitClick(object sender, EventArgs e)
    {
        Scanner.MyScann.Scanner.DeinitSymbolReader();
        this.Close();
        Application.Exit();
    }

Any help would be appreciated!

3

There are 3 answers

1
Bjørn-Roger Kringsjå On BEST ANSWER

I'm not familiar with the symbol library, but from what i can see the problem is the ReadNotify event being raised at some point after the "deinitialization" of the scanner.

What you should do in the MainForm.CloseScanner() void is to first remove ALL handles added in the MainForm.InitScanner() and then call Scanner.DeinitSymbolReader().

Edit: You should remove the handle with the -= operator, not assigning null reference.

Hope this helps.

0
Ionut Ciobanu On

My impression is that your application doesn't exit correctly with or without 'deinitSymbolReader'. It is possible that by calling deinitSymbolReader on a resource that has already been closed you are causing an access violation. Maybe you should try giving up deinintSymbolReader, and try to also Dispose the scanner/trigger in the Form's Disposing Event.

What seems to be the problem is that you are Disposing of complex data structures, and right that you're changing them to null which basically means you're changing the reference and probably ensuring the GC will never get to free all the un-managed resources.

One indication that you are dealing with the improper manipulation of an un-managed resource is the fact that the second deinintSymbolReader shouldn't do anything (since all your resources are null) much less cause an error.

I have an application that uses triggers and scanner and it only needs an "enableScanner = false" and an "Scanner.Dispose()" if the scanner is not null.

1
user2210657 On

try not calling 'DeinitSymbolReader' on exit, and see if that fixes it

Pete