public ReportBase MonitorPulse(Object context, BackgroundWorker worker, int refreshMS)
{
Debug.WriteLine( String.Format( "{0}() ThreadID = {1}", System.Reflection.MethodInfo.GetCurrentMethod( ).Name, Thread.CurrentThread.ManagedThreadId ) );
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 pulse.") );
if ( _control.State != FunctionControl.FunctionState.Idle )
return new rfidSimpleReport( context, OperationOutcome.FailByContext, new Exception("Cannot pulse, 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( );
long asofTimeInElapsedMS = ElapsedMilliseconds;
rfidOperationReport report
= new rfidOperationReport( context,
asofTimeInElapsedMS,
RequestCount,
RawAntennaCycleCount,
RawInventoryCycleCount,
BadPacketCount,
CRCErrorCount,
RawPacketCount,
RawRoundCount,
RawInventoryCount,
SessionUniqueTags,
RequestUniqueTags,
CurrentUniqueTags,
GetSessionRelativeSessionDuration(asofTimeInElapsedMS) );
_control.StartAction( );
//@@@@_managedAccess.Callback = PacketCallBackFromReader;
PerformanceCounter processorUtilizationCounter = null;
try
{
processorUtilizationCounter = new PerformanceCounter( "Processor", "% Processor Time", "_Total", "." );
}
catch ( Exception ) { }
//clark 2011.05.27 Inventory uses Conitnue mode
ReaderInterfaceThreadClass threadClass = new ReaderInterfaceThreadClass(_managedAccess, (int)ReaderHandle, true, RadioOperationMode.CONTINUOUS, strcTagFlag);
threadClass._reader = this; // HACK
Thread runnerThread = new Thread( new ThreadStart(threadClass.PulseThreadProc) );
runnerThread.Name = "MonitorPulse";
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.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);
data.Dispose();
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)
{
_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 )
{
processorUtilization = CounterSample.Calculate( sample, processorUtilizationCounter.NextSample( ) );
}
// 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( ); // wait for thread to end
// 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:
Debug.Assert( false );
outcome = OperationOutcome.Unknown;
break;
}
}
report.OperationCompleted( outcome,
ElapsedMilliseconds,
RequestCount,
RawAntennaCycleCount,
RawInventoryCycleCount,
BadPacketCount,
CRCErrorCount,
RawPacketCount,
RawRoundCount,
RawInventoryCount,
SessionUniqueTags,
RequestUniqueTags,
CurrentUniqueTags,
SessionDuration );
_control.Finished( );
if ( EnableLogging )
{
//Push data from buffer to file. And clear buffer.
PacketLogger.Flush();
}
return report;
}// MonitorPulse