public SRControlThread(int count, LMLoggers.LognLM log, Measurement meas, Detector det) { op = SROp.Nothing; SRCtrl = new SRControl(count, log, meas, det); opgate = new ManualResetEventSlim(false); callwait = new ManualResetEventSlim(false); cts = new CancellationTokenSource(); }
// need to call this AFTER the instruments are identified from the sys config internal void ConnectSRInstruments() { // start the control thread for each SR and and make sure it is waiting for a command IEnumerator iter = Instruments.Active.GetSREnumerator(); while (iter.MoveNext()) { SRInstrument sri = (SRInstrument)iter.Current; sri.SRCtrl = SRWrangler.StartSRControl(sri, pceh: (sender, args) => // the report progress eh { SRControl srctrl = args.UserState as SRControl; if (srctrl.IsInitialized) { SRWrangler.Logger.TraceEvent(LogLevels.Verbose, 383, "{0}, SRControl {1}: SR status '{2}', SR Control Status '{3}' ({4})", args.ProgressPercentage, srctrl.Identifier, INCCSR.SRAPIReturnStatusCode(srctrl.LastSRStatus), INCCSR.SRAPIReturnStatusCode(srctrl.LastMeasStatus), srctrl.fraction); } else { SRWrangler.Logger.TraceEvent(LogLevels.Verbose, 384, "{0}, SRControl {1}", args.ProgressPercentage, srctrl.Identifier); } }, // the operation complete eh opeh: SREventHandler ); } iter = Instruments.Active.GetSREnumerator(); // associate each new SR thread with the current measurement while (iter.MoveNext()) { SRInstrument sri = (SRInstrument)iter.Current; SRWrangler.StartSRActionAndWait(sri.id, SRTakeDataHandler.SROp.InitializeContext); } // devnote: the attempt to connect occurs in StartLMCAssay }
// register this using StartSRControl public static void SREventHandler(object sender, SRTakeDataHandler.SROpCompletedEventArgs e) { SRControl sr = (SRControl)e.UserState; // SRTakeDataHandler.SROp next = SRTakeDataHandler.NextOp(e.Op, e.OpStatus); sr.Log.TraceEvent(LogLevels.Verbose, 87266, "SR {0} operation {1} completed '{2}'", sr.Identifier, e.Op, INCCSR.SRAPIReturnStatusCode(e.OpStatus)); try { switch (e.Op) { case SRTakeDataHandler.SROp.Shutdown: break; case SRTakeDataHandler.SROp.Nothing: break; case SRTakeDataHandler.SROp.InitializeContext: break; case SRTakeDataHandler.SROp.InitializeSR: case SRTakeDataHandler.SROp.ReInitializeSR: if (!(e.OpStatus == INCCSR.SUCCESS || e.OpStatus == INCCSR.MEAS_CONTINUE)) { StopThisSRAssayImmediately((SRTakeDataHandler.SRControlThread)sender); //Action<object> action = (object obj) => //{ // StopThisSRAssayImmediately((SRTakeDataHandler.SRControlThread)obj); //}; //Task signifyingnothing = Task.Factory.StartNew(action, sender); } break; case SRTakeDataHandler.SROp.StartSRDAQ: if (!(e.OpStatus == INCCSR.SUCCESS || e.OpStatus == INCCSR.MEAS_CONTINUE)) { StopThisSRAssayImmediately((SRTakeDataHandler.SRControlThread)sender); //Action<object> action = (object obj) => //{ // StopThisSRAssayImmediately((SRTakeDataHandler.SRControlThread)obj); //}; //Task signifyingnothing = Task.Factory.StartNew(action, sender); } break; case SRTakeDataHandler.SROp.WaitForResults: if (!(e.OpStatus == INCCSR.SUCCESS || e.OpStatus == INCCSR.MEAS_CONTINUE)) { StopThisSRAssayImmediately((SRTakeDataHandler.SRControlThread)sender); //Action<object> action = (object obj) => //{ // StopThisSRAssayImmediately((SRTakeDataHandler.SRControlThread)obj); //}; //Task signifyingnothing = Task.Factory.StartNew(action, sender); } else { SRTakeDataHandler.SRControlThread srct = (SRTakeDataHandler.SRControlThread)sender; sr.Log.TraceEvent(LogLevels.Verbose, 87225, "Transform the results, or get the transformed results"); srct.sri.PendingComplete(); // when we get here, the raw results are already available on the SR thread structure if (srct.sri.DAQState == DAQInstrState.HVCalib) { } else { srct.SRCtrl.TransformResults(srct.SRCtrl.Det.Id, srct.sri.RDT.Cycle); // convert to enhanced results } HandleEndOfCycleProcessing(srct.sri); } break; case SRTakeDataHandler.SROp.CloseSR: break; } } catch (AnalysisDefs.CancellationRequestedException) // thrown from this method { StopActiveAssayImmediately(); } catch (Exception oddex) { sr.Log.TraceEvent(LogLevels.Error, 643, "Internal error, stopping active processing, {0}", oddex.Message); if (sender != null) { SRTakeDataHandler.SRControlThread srct = (SRTakeDataHandler.SRControlThread)sender; HandleFatalGeneralError(srct.sri, oddex); } else { // will blow if not really an Assay subclass, e.g. not running in the context of the full DAQCOntrol class CurState.State = DAQInstrState.Offline; // remaining buffers should now bypass DAQ section gControl.StopLMCAssay(removeCurNCDFile: false); // stop the instruments gControl.netlog.TraceException(oddex, false); gControl.netlog.TraceEvent(LogLevels.Info, 429, "DAQ processing incomplete: {0}, processing stopped", oddex.Message); //activeInstr.RDT.EndOfCycleProcessing(CurState.Measurement); gControl.MajorOperationCompleted(); // signal the controlling loop we are done } } }
void ThreadOp(object sender, DoWorkEventArgs ea) { SRControlThread srct = (SRControlThread)sender; SRControl sr = srct.SRCtrl; string identifier = "<unset>"; sr.Log.TraceEvent(LogLevels.Verbose, 87200, "Starting new SR thread"); try { identifier = sr.Identifier; sr.Log.TraceEvent(LogLevels.Verbose, 87201, "SR {0} thread running ", identifier); do { sr.Log.TraceEvent(LogLevels.Verbose, 87202, "SR {0} thread wait for command", identifier); try { srct.opgate.Wait(srct.cts.Token); // wait for caller to set an operation in motion } catch (OperationCanceledException) { //next: Should this do something. It is being thrown, but no action hn 9/23/2014 } if (CancellationRequested(srct)) { sr.Log.TraceEvent(LogLevels.Verbose, 87255, "SR {0} thread cancelled", identifier); break; } srct.callwait.Reset(); // make caller wait for results switch (srct.op) { case SROp.InitializeContext: sr.Log.TraceEvent(LogLevels.Verbose, 87203, "SR {0} InitializeContext", identifier); ushort numnutsd = sr.InitializeContext(sr.Meas, sr.Det); // sets sr.acquire_num_runs srct.ReportProgress(0, sr); break; case SROp.InitializeSR: try { sr.Log.TraceEvent(LogLevels.Verbose, 87204, "SR {0} InitializeSR", identifier); srct.status = sr.InitializeSR(srct.cts); if (srct.status != sr_h.SR_SUCCESS) // status here is an sr.h machine code only { // stop = true; caller will stop, thread itself cannot } ea.Result = srct.status; sr.InitTDState(); // uses sr.acquire_num_runs } catch (Exception e) { // do not set LastSRStatus because there may have never been one set, use the Meas status ea.Result = srct.status = srct.SRCtrl.LastMeasStatus = SR.SR_FAIL; sr.Log.TraceException(e, false); sr.Log.TraceEvent(LogLevels.Warning, 87259, "SR {0} InitializeSR failure ", identifier); } srct.ReportProgress(0, sr); break; case SROp.StartSRDAQ: sr.Log.TraceEvent(LogLevels.Verbose, 87205, "SR {0} StartSRDAQ", identifier); srct.status = sr.StartSRDAQ(); if (srct.status != SR.MEAS_CONTINUE) // MEAS_ABORT or MEAS_TERMINATE { // stop = true; caller will stop, thread itself cannot } ea.Result = srct.status; srct.ReportProgress((int)(100 * ((double)sr.run_number / (double)sr.acquire_num_runs)), sr); break; case SROp.WaitForResults: sr.Log.TraceEvent(LogLevels.Verbose, 87206, "SR {0} PollAndGetResults", identifier); srct.status = sr.PollAndGetResults(); ea.Result = srct.status; if ((srct.status == SR.ZERO_COUNT_TIME) || (srct.status == SR.SR_TRY_AGAIN)) // dev note: empty cycles are eliminated by this step { sr.run_number--; } else if (srct.status != SR.SUCCESS) // MEAS_ABORT or MEAS_TERMINATE { // stop = true; caller will stop, thread itself cannot } else { // sr.tds has the results now, caller must retrieve them manually using TransformResults sr.fraction += sr.Meas.AcquireState.run_count_time; // run this out-of-thread so that caller wait is reset prior to the restart in StartLMCAssay! Action <object> action = (object obj) => { SRControlThread talsrct = (SRControlThread)obj; talsrct.SROpCompletedEvent(talsrct.status); }; Task signifyingnothing = Task.Factory.StartNew(action, srct); } srct.ReportProgress((int)(100 * ((double)sr.run_number / (double)sr.acquire_num_runs)), sr); break; case SROp.CloseSR: sr.Log.TraceEvent(LogLevels.Verbose, 87207, "SR {0} CloseDownSR", identifier); sr.CloseDownSR(); srct.ReportProgress(100, sr); break; case SROp.Shutdown: sr.Log.TraceEvent(LogLevels.Verbose, 87207, "SR {0} shutdown thread", identifier); break; case SROp.ReInitializeSR: try { sr.Log.TraceEvent(LogLevels.Verbose, 87208, "SR {0} ReInitializeSR", identifier); srct.status = sr.ReInitializeSR(); if (srct.status != sr_h.SR_SUCCESS) // status here is an sr.h machine code only { // stop = true; caller will stop, thread itself cannot } ea.Result = srct.status; sr.InitTDState(); // uses sr.acquire_num_runs } catch (Exception e) { // do not set LastSRStatus because there may have never been one set, use the Meas status ea.Result = srct.status = srct.SRCtrl.LastMeasStatus = SR.SR_FAIL; sr.Log.TraceException(e, false); sr.Log.TraceEvent(LogLevels.Verbose, 87260, "SR {0} ReInitializeSR failure ", identifier); } srct.ReportProgress(0, sr); break; } srct.opgate.Reset(); // wait again at the top of loop, but first check for cancel or stop in the while condition here srct.callwait.Set(); // release caller to get state and do work } while (!(srct.op == SROp.Shutdown) || CancellationRequested(srct)); // run until a cancel occurs, or caller specifies the Shutdown operation } catch (Exception e) { sr.Log.TraceException(e, true); sr.Log.TraceEvent(LogLevels.Verbose, 87257, "SR ThreadOp bonk {0}", identifier); } sr.Log.TraceEvent(LogLevels.Verbose, 87297, "SR {0} thread exiting", identifier); srct.callwait.Set(); // release caller to get state and do work //srct.SROpCompletedEvent(srct.status); // signal failure via the final event if ungraceful exit in play }