RFID.RFIDInterface.LakeChabotReader.ReadInventory C# (CSharp) Method

ReadInventory() public method

public ReadInventory ( Object context, BackgroundWorker worker, int refreshMS ) : ReportBase
context Object
worker BackgroundWorker
refreshMS int
return ReportBase
        public ReportBase ReadInventory( Object context, BackgroundWorker worker, int refreshMS )
        {
#if DEBUG
            System.Diagnostics.Debug.WriteLine( String.Format( "{0}() ThreadID = {1}", System.Reflection.MethodInfo.GetCurrentMethod( ).Name, Thread.CurrentThread.ManagedThreadId ) );
#endif

            if ( IsDisposed )
            {
                throw new ObjectDisposedException( "LakeChabotReader" );
            }

            if ( Mode != rfidReader.OperationMode.BoundToReader )
            {
                return new rfidSimpleReport( context, OperationOutcome.FailByContext,
                    new rfidException( rfidErrorCode.ReaderIsNotBound, "Reader must be bound before inventory can be read." ) );
            }

            if ( _control.State != FunctionControl.FunctionState.Idle )
            {
                return new rfidSimpleReport( context, OperationOutcome.FailByContext, new Exception( "Cannot read the inventory, the prior task has not completed" ) );
            }

            if ( null == worker )
            {
                return new rfidSimpleReport( context, OperationOutcome.FailByApplicationError, new ArgumentNullException( "worker", "BackgroundWorker is required" ) );
            }

            if ( refreshMS < MIN_REFRESH_MS || refreshMS > MAX_REFRESH_MS )
                return new rfidSimpleReport( context, OperationOutcome.FailByApplicationError, new ArgumentOutOfRangeException( "refreshMS", refreshMS, string.Format( "Value must be between {0} and {1}", MIN_REFRESH_MS, MAX_REFRESH_MS ) ) );


            _refreshRateMS = refreshMS;
            _bgdWorker = worker;
            _requestTagList.Clear( );
            _periodTagList.Clear( );
            rfidOperationReport report
                = new rfidOperationReport( context,
                                           ElapsedMilliseconds,
                                           RequestCount,
                                           RawAntennaCycleCount,
                                           RawInventoryCycleCount,
                                           BadPacketCount,
                                           CRCErrorCount,
                                           RawPacketCount,
                                           RawRoundCount,
                                           RawInventoryCount,
                                           SessionUniqueTags,
                                           RequestUniqueTags,
                                           CurrentUniqueTags,
                                           SessionDuration );

            _control.StartAction( );

            PerformanceCounter processorUtilizationCounter = null;

            long t1 = HighResolutionTimer.Microseconds;
            try
            {
                processorUtilizationCounter = new PerformanceCounter( "Processor", "% Processor Time", "_Total", "." );
            }
            catch ( Exception )
            {
                Debug.WriteLine( "Unable to start processorUtilizationCounter" );
            }

            t1 = HighResolutionTimer.Microseconds - t1;

            Debug.WriteLine( String.Format( "processorUtilizationCounter startup time {0} us", t1 ) );

            //clark 2011.05.27  Inventory Once uses Non-Conitnue mode
            ReaderInterfaceThreadClass threadClass = new ReaderInterfaceThreadClass(_managedAccess, (int)ReaderHandle, true, RadioOperationMode.NONCONTINUOUS, strcTagFlag);
            threadClass._reader = this; // HACK
            Thread runnerThread = new Thread( new ThreadStart( threadClass.InventoryThreadProc ) );
            runnerThread.Name = "ReadInventory";
            runnerThread.IsBackground = true;
            runnerThread.Priority = ThreadPriority.BelowNormal;
            runnerThread.Start( );

            int notused = FileHandler.TotalPacketCount; // Make sure the file is created;

            // Wait for thread to be in ready stat
            int counter = 500;
            while ( counter-- > 0 && ( int ) ( runnerThread.ThreadState & System.Threading.ThreadState.WaitSleepJoin ) == 1 )
            {
                Thread.Sleep( 10 );
            }
            if ( !runnerThread.IsAlive )
            {
                return new rfidSimpleReport( context, OperationOutcome.FailByApplicationError, new ApplicationException( "BackgroundWorker thread could not be started." ) );
            }

            ReaderRequest readerRequest = new ReaderRequest( );

            readerRequest.reader = _theReaderID.Name;
#pragma warning disable 420 // reference to a volatile field is valid for Interlocked call
            readerRequest.requestSequence = System.Threading.Interlocked.Increment( ref _commonRequestIndex );
#pragma warning restore 420
            readerRequest.requestName = rfidReader.GetNameForRequest( rfidReader.ReaderRequestType.GetInventory );
            readerRequest.startTime = GetSessionRelativeDateTime( report.StartTimeMS );
            readerRequest.requestStartTime = report.StartTimeMS;
            readerRequest.startingPacketCount = RawPacketCount;
            readerRequest.startingTagCount = RawInventoryCount;

            MemoryStream data = new MemoryStream( );
            readerRequest.WriteTo( data );
            PacketData.PacketWrapper pseudoPacket = new PacketData.PacketWrapper( new PacketData.CommandPsuedoPacket( readerRequest.requestName, data.ToArray( ) ), PacketData.PacketType.U_N_D_F_I_N_E_D );
            pseudoPacket.IsPseudoPacket = true;
            pseudoPacket.ReaderName = _theReaderID.Name;
            pseudoPacket.ReaderIndex = ( int ) _theReaderID.Handle;
            FileHandler.WritePacket( pseudoPacket );

            DateTime ReportDue = DateTime.Now.AddMilliseconds( refreshMS );
            threadClass.StartEvent.Set( );

            while ( runnerThread.IsAlive )
            {
                CounterSample sample = CounterSample.Empty;
                if ( processorUtilizationCounter != null )
                {
                    try
                    {
                        sample = processorUtilizationCounter.NextSample( );
                    }
                    catch ( Exception ) { }
                }
                ProcessQueuedPackets( );

                QueueEvent.WaitOne( 30, true );
                QueueEvent.Reset( );

                DateTime now = DateTime.Now;

                if ( ReportDue.Ticks <= now.Ticks )
                {
                    // Debug.WriteLine(String.Format("Reporing Progress Now (Elapsed Milliseconds {0})", ElapsedMilliseconds));
                    _bgdWorker.ReportProgress(
                        0,
                        report.GetProgressReport(
                            ElapsedMilliseconds,
                            RequestCount,
                            RawAntennaCycleCount,
                            RawInventoryCycleCount,
                            BadPacketCount,
                            CRCErrorCount,
                            RawPacketCount,
                            RawRoundCount,
                            RawInventoryCount,
                            SessionUniqueTags,
                            RequestUniqueTags,
                            CurrentUniqueTags,
                            SessionDuration ) );
                    _periodTagList.Clear( );
                    ReportDue = now.AddMilliseconds( refreshMS );
                }

                if ( !runnerThread.IsAlive )
                    break;

                if ( FunctionController.GetActionRequest( ) == FunctionControl.RequestedAction.Abort )
                {
                    threadClass.Stop = true;
                    Result abortError = Result.OK;
                    try
                    {
                        abortError = LakeChabotReader.MANAGED_ACCESS.API_ControlAbort();
                    }
                    catch ( Exception e )
                    {
                        Debug.WriteLine( String.Format( "Error attempting to abort: {0}", e.Message ) );
                    }
                    break;
                }

                if ( FunctionController.GetActionRequest( ) == FunctionControl.RequestedAction.Stop )
                {
                    threadClass.Stop = true;
                    Result stopError = Result.OK;
                    try
                    {
                        stopError = LakeChabotReader.MANAGED_ACCESS.API_ControlCancel();
                    }
                    catch ( Exception e )
                    {
                        Debug.WriteLine( String.Format( "Error attempting to stop: {0}", e.Message ) );
                    }
                    if ( Result.OK != stopError )
                    {
                        // Try to abort
                    }
                    break;
                }

                if ( FunctionController.State == FunctionControl.FunctionState.Paused )
                {
                    do
                    {
                        Thread.Sleep( refreshMS );
                    } while ( FunctionController.State == FunctionControl.FunctionState.Paused );
                }

                if ( !runnerThread.IsAlive )
                    break;

                float processorUtilization = 0;

                if ( processorUtilizationCounter != null && sample == CounterSample.Empty )
                {
                    try
                    {
                        processorUtilization = CounterSample.Calculate( sample, processorUtilizationCounter.NextSample( ) );
                    }
                    catch ( Exception ) { }
                }
                // Debug.WriteLine(String.Format("Processor Util: {0}", processorUtilization));

                if ( processorUtilization > ( float ) TARGET_MAX_USAGE_PERCENT )
                    _packetSleepMS += SLEEP_ADD_SUBTRACT_MS;
                else
                    _packetSleepMS -= _packetSleepMS <= MIN_SLEEP_TIME_MS ? 0 : SLEEP_ADD_SUBTRACT_MS;
            }

            runnerThread.Join( );

            // Get any leftover packets
            ProcessQueuedPackets( );

            if ( LastCommandResult != 0 ) MacClearError( );

            OperationOutcome outcome = OperationOutcome.Success;
            string result = threadClass.Result;

            if ( !( result == null || result == "" || result == "OK" ) )
            {
                switch ( _control.State )
                {
                    case FunctionControl.FunctionState.Stopping:
                        outcome = OperationOutcome.SuccessWithUserCancel;
                        break;

                    case FunctionControl.FunctionState.Aborting:
                        outcome = OperationOutcome.FailByUserAbort;
                        break;

                    case FunctionControl.FunctionState.Running:
                    // outcome = OperationOutcome.FailByReaderError;
                    // report.ErrorMessage = result;
                    // break;

                    case FunctionControl.FunctionState.Idle:
                    case FunctionControl.FunctionState.Paused:
                    case FunctionControl.FunctionState.Unknown:
                    default:
                        outcome = OperationOutcome.Unknown;
                        break;
                }
            }

            _control.Finished( );

            report.OperationCompleted( outcome,
                                       ElapsedMilliseconds,
                                       RequestCount,
                                       RawAntennaCycleCount,
                                       RawInventoryCycleCount,
                                       BadPacketCount,
                                       CRCErrorCount,
                                       RawPacketCount,
                                       RawRoundCount,
                                       RawInventoryCount,
                                       SessionUniqueTags,
                                       RequestUniqueTags,
                                       CurrentUniqueTags,
                                       SessionDuration );

            if ( EnableLogging )
            {
                //Push data from buffer to file. And clear buffer.
                PacketLogger.Flush(); 
            }

            return report;
        }